C++
namespace
cin cout
cout<< hex or oct or dec 十六进制 八进制 十进制
cout<<showpoint 显示小数点
cout<<noshowpoint
cout << fixed 显示定点数 d.ddddd格式
cout.unsetf(ios_base::fixed); 取消定点数显示
cout << setprecision(3) 在设置了fixed之后设置显示精度,表示显示3位小数
cout << setw(6) 显示宽度为6位, 这个仅仅生效一次, 生效完毕后自动为setw(0)
cout << setfill('0') 设置填充字符,默认为空格字符
cout << left 左对齐
cout << right 右对齐 默认是右对齐
cout << boolalpha 显示布尔值为字符形式
cout << scientific 显示小数为科学记数法格式 0.037608 ===> 3.760800e-02
运算符重载的知识点:
1、可以被重载的运算符有
new new[] delete delete[]
+ - * / % ^ & | ~ ! = < > += -= *= /= %=
^= &= |= << >> <<= >>= == != <= >= && || ++
-- , ->* -> () []
其中,+ - * & 的一元、二元形式都可以被重载,自增运算符++和自减运算符--的前置、后置形式都可以被重载。
2、不可以被重载的运算符有:
成员选择符. 成员对象选择符.* 域解析操作符:: 条件操作符?:
3、一般来说,运算符可以有两种重载方式:
a、可以用类的成员函数形式来重载
a+b ====> a.operator+(b) 通常只有1个参数
b、可以用不属于类的顶层函数形式来重载,通常会声明成类的friend友元函数,
这将至少带有一个类对象参数,否则都是内建类型(如2+3,就不需要重载运算符了)。
a+b ====> operator+(a, b) 通常要有2个参数
c、operator<<只能以顶层函数形式重载,如果重载为类的成员函数,那么就只能是ostream类的成员函数,但是我们不能修改系统的源码,所以只有重载成顶层函数的形式了。
4、下标操作符[]、赋值操作符=、函数调用操作符()和指针操作符->必须以类的成员函数的形式重载。
5、下标运算符的重载形式一般有两种:
可读写数组元素
class A{
//...
returntype& operator[](paramtype);
//...
};
或
只读方式
class A{
//...
const returntype& operator[](paramtype) const;
//...
};
6、自增++
前置++a
operator++();
and
后置a++
operator++(int); //参数没有用它,只是用来区分前后置的。
异常处理:
try{
cout << c[2] << endl;
}
catch(string except){
if(except == "outofrange")
{
cerr << "your array index is out of range!" << endl;
exit(1);
}
}
static成员变量:
1、它是整个类共有的,只有1份拷贝。
class A{
static int i;
};
int A::i;
int main()
{
A a, b;
a.i = 10;
b.i = 20;
cout << a.i << b.i;
结果应该都是20
}
2、它既可以象普通成员变量一样去访问,也可以直接使用类名去访问。
A a; a.i = 100;
A::i = 100;
static成员函数:
1、它既可以象普通成员函数一样用对象去调用,也可以直接使用类名去调用。
A a; a.display();
A::display();
2、它只能访问静态成员变量,不能访问普通成员变量。
int main()
{
Person a("xiaoming", 12); //在main函数栈上创建的a对象,不用我们回收,栈会自动回收它的空间
a.display();
//在堆上创建了一个Person类的对象,需要我们自己去回收,使用delete回收它的空间
Person *pa = new Person("xiaoming", 12);
pa->display();
delete pa;
return 0;
}
static静态成员变量
它是属于整个类所共有的数据,类中只有唯一的一份,大家都一样。通过这个类的每一个对象去访问它都会让别的对象知道这个改变。
静态成员变量不属于具体的某一个对象,而是属于整个类,所以它不存储在对象的数据中,存在静态存储区中。
访问静态成员变量的方法和普通成员变量有区别
普通成员变量:先创建对象,然后由对象和成员选择符"."才能去访问,比如
A a;
a.age = 10;
静态成员变量:可以象普通成员变量一样用对象名和成员选择符一样去访问,还可以不创建对象,一样能访问。
A::age = 10;
静态成员函数不能访问普通成员变量,只能访问静态成员变量;普通成员函数两者都能访问
静态成员函数和静态成员变量类似,它属于整个类所共有,可以不创建这个类的对象就调用它。
A::goo();
类比下普通成员函数的调用
A a;
a.foo();
C里的static有什么含义?
一个不属于类的局部变量加了static,变量生命期延长了,整个程序的生命期,但是作用域不变,仍旧是局部变量。
一个不属于类的全局变量前加static,变量生命期不变,但是作用域改变为只能在本文件中使用。
一个不属于类的函数前加上static,函数只能被本目标文件范围内的函数调用,不能被其他文件调用。
the big three
继承
class A{
//...
};//基类
class B : public A{
//...
};//派生类
父类指针可以指向子类对象
但是子类指针不可指向父类对象,强制如此的话,访问会不安全。
子类里面实现了一个和父类里的函数同名的一个新函数的话,这称为子类的这个函数遮住了父类的同名函数.遮挡不会去查看参数数否一致,只关心函数名字是否一样,一样就遮住hide(隐藏)了。
在类定义时:
class A{
public: //公有的 被属于这个类的函数访问,也可以被不属于这个类的其他类的函数访问,还可以被象main函数那样不属于任何类的顶层函数访问。
//...
int a;
void goo();
protected: //保护的 可以被属于这个类的成员函数访问,也可以被派生类的函数访问,但除此以外的其他类的成员函数以及main函数之类的顶层函数都不能访问protected成员。
//...
int b;
void hoo();
private: //私有的 只能被属于这个类的成员函数访问。派生类也是一个新的类型,派生类的成员函数也不能访问private的成员,main函数之类的顶层函数更不能访问到private成员了。
//...
int c;
void foo();
};
int main()
{
A obj;
obj.a = 10;//ok! public
obj.goo(); //ok! public
obj.c = 10; //error! private
obj.foo(); //error! private
}
继承时的方法,也分成了三种 public protected private
class A{
public:
int a;
void foo();
protected:
int b;
private:
int c;
};
public方式继承
class B : public A{
//以下是B类自己的函数
void goo();
//以下这些成员是从父类继承过来的,看不见,但实际存在,我们把它们的权限写下来:
int A::a; //public
int A::b; //protected
int A::c; //不可见,在B类的函数goo()里不可访问它,但是可以通过调用A类的A::foo()来访问它。
};
protected方式继承
class B : protected A{
//以下是B类自己的函数
void goo();
//以下这些成员是从父类继承过来的,看不见,但实际存在,我们把它们的权限写下来:
int A::a; //protected
int A::b; //protected
int A::c; //不可见,在B类的函数goo()里不可访问它,但是可以通过调用A类的A::foo()来访问它。
};
private方式继承
class B : private A{
//以下是B类自己的函数
void goo();
//以下这些成员是从父类继承过来的,看不见,但实际存在,我们把它们的权限写下来:
int A::a; //private
int A::b; //private
int A::c; //不可见,在B类的函数goo()里不可访问它,但是可以通过调用A类的A::foo()来访问它。
};
一个常见的问题:
请你讲讲C++中overload、override、hide之间有什么区别?
overload 重载
在同一个类,或者同一个区域(顶层函数),函数的名字相同,但是函数的参数不同(包括参数类型和个数不同),这个称为重载,比如
int add(int a, int b);
double add(double a, double b);
类中的构造函数重载
class A{
public:
A();
A(int a);
A(const A& a); //拷贝构造函数
};
override 重写或覆盖
override是指在不同区域中(父类、子类区域不同),有一模一样的函数(返回值、函数名、参数列表都要一样),同时这些函数都有virtual关键字,这时称为子类的这些函数覆盖或重写了(override)父类的同名函数。当调用这些同名函数的时候,依据对象的真实类型(而不是指向对象的指针类型),调用对应类型里的函数实现。
比如:多态的例子
hide 隐藏、遮住
当调用这些同名函数的时候,依据指向对象的指针类型(栈上创建的对象,依据对象类型),调用对应类型里的函数实现。
hide和override的共同点:
函数分别在父类、子类的不同区域。
hide和override类似,仅仅有如下两个地方不同:
a、hide针对的是没有virtual的非虚函数
b、hide的函数即使参数列表不一样,但只要函数名一样,也构成隐藏。
比如:
class A{
public:
void foo();
};
class B:public A{
public:
void foo(int a);//隐藏了父类的A::foo()函数,即使参数不同。
void foo(); //一样隐藏了父类的A::foo()函数
};