我们可以思考一下,当我们定义一个形式上空的类,C++为这个类提供了哪些默认功能?是否可以说齐全呢?
有些看起来理所当然的东西,也是需要默认实现的。
看简单代码
#include <iostream> class TTestClass{}; int main(int argc, char **argv) { TTestClass tc; TTestClass *p = &tc; tc = *p; delete p; }
-
TTestClass tc; 说明C++提供了默认的拷贝构造函数。
-
TTestClass *p = &tc; 表明C++为类实现了取得地址运算符。
-
tc = *p; 代表C++ 实现了赋值操作符号
-
delete p; 代表实现了析构函数。
因此可以总结一下,C++ class 的默认接口大致为
class TObject{ public: TObject(); ~TObject(); TObject(const TObject &src); TObject &operator=(const TObject &src); TObject *operator&(const TObject &src); };
另外注意语句
TTestClass tc = xxx;
仅仅调用了拷贝构造函数。区分"="是赋值还是copy constructor的关键就是要看"="左边的对象已经构造了没有
- 如果已经构造了,就是进行赋值操作
- 如果还没有构造,就是进行copy构造函数
下面的代码证明了上述观点
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream>
class TestClass{
private:
int data;
public:
TestClass(): data(-1){
std::cout<<"Default Constructor"<<std::endl;
}
TestClass(const TestClass &src){
std::cout<<"Copy Constructor"<<std::endl;
}
~TestClass(){
std::cout<<"Default Destructor"<<std::endl;
}
TestClass& operator=(const TestClass &src){
std::cout<<"Asign Value Operator"<<std::endl;
memcpy(this, &src, sizeof(src));
return *this;
}
void setData(int data){
this->data = data;
}
int getData(){
return data;
}
};
int main()
{
TestClass tc; //默认构造
tc.setData(0);
TestClass tc1 = tc; //拷贝构造
TestClass tc2(tc); //拷贝构造
TestClass tc3;// 默认构造
tc3 = tc; // 赋值操作
std::cout<<tc.getData()<<" "<<tc1.getData()<<" "<<tc2.getData()<<" "<<tc3.getData()<<std::endl;
return 0;
}
运行结果为
Default Constructor
Copy Constructor
Copy Constructor
Default Constructor
Asign Value Operator
0 4247360 -1859193535 0
Default Destructor
Default Destructor
Default Destructor
Default Destructor
请按任意键继续. . .
注意 中间两个的结果数值诡异的原因是我们写的拷贝构造函数没有真的copy,应该向赋值操作那样memcpy一下
最后对象销毁,执行了三次析构函数