// Testing.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
using namespace std;
class baseClass
{
public:
baseClass()
{
cout << "基类构造函数被调用" <<endl;
}
virtual ~baseClass()
{
cout << "基类的析构函数应该是虚函数, 子类才能被正确析构" <<endl;
}
};
class Test1:public baseClass
{
public:
Test1()
{
cout << "子类构造函数被调用" <<endl;
}
Test1(char* pChar)
{
m_pChar = pChar;
cout << "子类构造函数被调用" <<endl;
}
~Test1()
{
cout << "子类析构函数被调用" <<endl;
}
Test1(const Test1 &t)
{
char* pTemp = m_pChar;
m_pChar = new char[5];
strcpy(m_pChar, t.m_pChar);
if(!pTemp)
delete []pTemp;
cout << "拷贝构造函数被调用,重新分配内存资源" <<endl;
}
Test1& operator =(const Test1 &t)
{
if(this == &t)
return *this;
char* pTemp = m_pChar;
m_pChar = new char[5];
strcpy(m_pChar, t.m_pChar);
if(!pTemp)
delete []pTemp;
cout << "操作符重载函数被调用,重新分配内存资源" <<endl;
}
private:
char* m_pChar;
};
void foo(Test1 b)
{
}
int _tmain(int argc, _TCHAR* argv[])
{
// 测试虚析构函数
cout << " 测试构造 虚析构函数.........................................." <<endl;
baseClass *b = new Test1();
delete b;
// 测试拷贝构造函数
cout << " 测试拷贝构造函数.........................................." <<endl;
Test1 sub("aaaa");
Test1 sub2 = sub;
Test1 sub3(sub);
foo(sub);
// 测试操作符重载函数
cout << " 测试操作符重载函数.........................................." <<endl;
Test1 sub4("bbbb");
Test1 sub5;
sub5 = sub4;
return 0;
}
C++拷贝构造函数的几个细节
C++拷贝构造函数的几个细节(转自:http://grantren.javaeye.com/blog/43289)
一 拷贝构造函数是C++最基础的概念之一,大家自认为对拷贝构造函数了解么?请大家先回答一下三个问题:
1. 以下函数哪个是拷贝构造函数,为什么?
- X::X(const X&);
- X::X(X);
- X::X(X&, int a=1);
- X::X(X&, int a=1, b=2);
2. 一个类中可以存在多于一个的拷贝构造函数吗?
3. 写出以下程序段的输出结果, 并说明为什么? 如果你都能回答无误的话,那么你已经对拷贝构造函数有了相当的了解。
- #include
- #include
- struct X {
- template<typename T>
- X( T& ) { std::cout << "This is ctor." << std::endl; }
- template<typename T>
- X& operator=( T& ) { std::cout << "This is ctor." << std::endl; }
- };
- void main() {
- X a(5);
- X b(10.5);
- X c = a;
- c = b;
- }
解答如下:
1. 对于一个类X,如果一个构造函数的第一个参数是下列之一:
a) X&
b) const X&
c) volatile X&
d) const volatile X&
且没有其他参数或其他参数都有默认值,那么这个函数是拷贝构造函数.
- X::X(const X&); //是拷贝构造函数
- X::X(X&, int=1); //是拷贝构造函数
2.类中可以存在超过一个拷贝构造函数,
- class X {
- public:
- X(const X&);
- X(X&); // OK
- };
注意,如果一个类中只存在一个参数为X&的拷贝构造函数,那么就不能使用const X或volatile X的对象实行拷贝初始化.
- class X {
- public:
- X();
- X(X&);
- };
- const X cx;
- X x = cx; // error
如果一个类中没有定义拷贝构造函数,那么编译器会自动产生一个默认的拷贝构造函数.
这个默认的参数可能为X::X(const X&)或X::X(X&),由编译器根据上下文决定选择哪一个.
默认拷贝构造函数的行为如下:
默认的拷贝构造函数执行的顺序与其他用户定义的构造函数相同,执行先父类后子类的构造.
拷贝构造函数对类中每一个数据成员执行成员拷贝(memberwise Copy)的动作.
a)如果数据成员为某一个类的实例,那么调用此类的拷贝构造函数.
b)如果数据成员是一个数组,对数组的每一个执行按位拷贝.
c)如果数据成员是一个数量,如int,double,那么调用系统内建的赋值运算符对其进行赋值.
3. 拷贝构造函数不能由成员函数模版生成.
- struct X {
- template<typename T>
- X( const T& ); // NOT copy ctor, T can't be X
- template<typename T>
- operator=( const T& ); // NOT copy ass't, T can't be X
- };
原因很简单, 成员函数模版并不改变语言的规则,而语言的规则说,如果程序需要一个拷贝构造函数而你没有声明它,那么编译器会为你自动生成一个. 所以成员函数模版并不会阻止编译器生成拷贝构造函数, 赋值运算符重载也遵循同样的规则.(参见Effective C++ 3edition, Item45)
二 针对上面作者的讨论,理解更深了,但是下面我还是会给出一个一般的标准的实现和注意事项:














































































