C++11新增的类功能
特殊的成员函数的提供规则
如果您提供了析构函数,复制构造函数或复制赋值运算符
那么移动构造函数和移动赋值运算符将不会被自动提供
如果您提供了移动构造函数或移动赋值运算符
那么复制构造函数和复制构造运算符将不会被自动提供
用default和delete对方法进行管理
TestClass();
explicit TestClass(const string & newmessage) ;
TestClass(TestClass && f);
TestClass & operator=(TestClass && f) ;
TestClass(const TestClass &f) = default;
TestClass & operator=(const TestClass &f) = default;
TestClass operator+(const TestClass &f) const;
void NotoUse() = delete;
void showObject() const;
~TestClass();
运用default显示地声明复制构造函数和复制赋值运算符的默认版本
在使用delete关键字禁用函数后,调用NotToUse方法将会被视为编译错误
继承构造函数
使用using可以让派生类使用基类的非特殊成员函数,或是让派生类继承基类的构造函数
class A
{
public:
A(int i = 100) : _i(i) {}
A(int i, double j) : _i(i) {
cout<<"using A constructor A(int,double)"<< endl;
}
inline int fn(double i)
{
cout << "Enter the A: int fn(double)" << endl;
return (int)i;
}
inline double fn(int i)
{
cout << "Enter the A: double fn(int)" << endl;
return (double)i;
}
private:
int _i;
};
class B: public A{
public:
using A::A; // 继承A的构造函数
//让A的fn函数对B可用。
//原本的情况下,因为没有声明为虚,所以只要子类声明了函数名fn(并特征标),A中的fn就会不可见
using A::fn;
B ():A() {}
B (int i):A(i){
cout << "using B constructor B(int)" << endl;
}
B (double j):A(),_j(j){}
inline double fn(int i){
cout << "Enter the B: double fn(int)" << endl;
return (double)i;
}
private:
double _j;
};
int main(){
B b1;
B b2(20); // 使用B的构造函数
B b3(1,2.0); // 从B中没有相匹配的构造函数,继承后使用了A的构造函数A(int,double)
b3.fn(3); // 调用B中的double fn(int)
b3.fn(2.0); // 调用A中的int fn(double)
}
对应输出
using B constructor B(int)
using A constructor A(int,double)
Enter the B: double fn(int)
Enter the A: int fn(double)
virtual 和 override的组合使用
对于基类声明的虚方法,子类在重载时可以在参数列表后面加上override。如果声明与基类方法不匹配,编译器将视为错误
/**
* A中声明的虚方法
**/
virtual inline double fn(int i)
{
cout << "Enter the A: double fn(int)" << endl;
return (double)i;
}
/**
* B对A的重载
**/
inline double fn(double i) override{
cout << "Enter the B: double fn(int)" << endl;
return (double)i;
}
特征标不匹配,编译阶段出错
using.cpp:40:19: error: 'double B::fn(double)' marked 'override', but does not override
inline double fn(double i) override{
编程中的一些小地方
静态变量必须先初始化,不然就会出现未定义的引用,且类的静态数据成员的初始化必须在类外进行
复制构造函数和复制赋值运算符
// 这是初始化,此时调用的是复制构造函数
TestClass test3 = test1;
//test1是左值,调用的是复制赋值运算符
TestClass test3;
test3 = test1;