类--复制构造函数、析构函数
2012-07-16 09:03
148 查看
1、如果没有显示定义复制构造函数或赋值操作符,编译器通常会为我们定义。
2、复制构造函数、赋值操作符、析构函数总称复制控制。编译器自动实现这些操作,蛋类也可以定义自己的版本。
3、有一种特别常见的情况需要类定义自己的复制控制成员的:类具有指针成员。
复制构造函数
1、是一种特殊的构造函数,具有单个形参,该形参(常用const修饰)是对该类类型的引用。
2、当形参或返回值为类类型时,有复制构造函数进行复制。
3、即使我们定义了其他构造函数,也会合成复制构造函数。,他的行为是,执行逐个成员初始化,将新对象初始化为原对象的副本。
4、为了防止复制,类必须显示声明其复制构造函数为private。
如果想要连友元和成员中的复制也禁止,就可以声明一个private复制构造函数但不对其定义。
5、声明而不定义成员函数式合法的,但是使用为定义成员的人和尝试将导致连接失败。
6、大多数类应定义复制构造函数和默认构造函数。
7、如果定义了复制构造函数,也必须定义默认构造函数。
复制构造函数以下部分来自百度百科:
何时使用复制构造函数:按值传递对象,函数返回对象,用一个对象初始化另一个对象(即复制初始化),根据元素初始化列表初始化数组元素,这四种情况都将调用复制构造函数。记住:复制构造函数只能用于初始化,不能用于赋值,赋值时不会调用复制构造函数,而是使用赋值操作符。
复制初始化与复制构造函数:复制初始化使用=等于符号来初始化,复制初始化也是创建一个新对象,并且其初值来自于另一个已存在的对象,复制初始化总是调用复制构造函数来初始化的。复制初始化时,首先使用指定的构造函数创建一个临时对象,然后用复制构造函数将临时对象的每个非static成员依次的复制到新创建的对象,复制构造函数执行的是逐个成员初始化。注意,这里是用一个已存在的对象创建另一个新对象,与用构造函数直接创建一个新对象不一样,使用构造函数初始化时不会使用另一个对象。比如有类hyong,则语句hyong
m(1,2)调用构造函数直接初始化,而语句hyong n=m则是用已存在的对象m去初始化一个新对象n,属于复制初始化。
理解赋值与复制初始化的区别(重点):赋值是在两个已存在的对象间进行的,也就是用一个已存在的对象去改变另一个已存在对象的值。赋值将调用赋值操作符对对象进行操作,赋值操作符将在操作符重载中讲解。比如有类hyong,有语句hyong x(1);hyong y(1,2)则x=y;这就是赋值,因为对象x和y是已经存在的对象,而语句hyong x=y;则是复制初始化,是用一个已存在的对象y去创建一个新对象x,所以是复制初始化。
复制初始化和赋值是在两个对象之间进行的操作,而直接初始化则不是
复制构造函数的形式:hyong(const hyong & obj);它接受一个指向类对象的常量引用作为参数。定义为const是必须的,因为复制构造函数只是复制对象,所以没必要改变传递来的对象的值,声明为引用可以节省时间,如果是按值传递的话就会生成对象的副本,会浪费资源,而引用就不会。
为什么需要定义自己的复制构造函数:如果类只包含类类型成员和内置类型的成员,则可以不用显示定义复制构造函数。但如果类中包含有指针或者有分配其他类型资源时,就必须重新定义复制构造函数。因为类中有指针成员,当把用一个对象初始化另一个对象时,这时两个对象中的指针都指向同一段内存,这时如果其中一个对象被消毁了,这时对象中指针所指向的内存也同样被消毁,但另一个对象确不知道这种情况,这时就会出现问题。比如hyong类中含有一个成员指针p,当声明了hyong x=y其中y也是hyong类的对象,这时对象x和y中的指针成员p都指向同一段内存,而如果y被消毁,但x还没被消毁时就会出问题,这时y中对象的成员指针p已经释放了该内存资源,而x中的成员指针p还不知道已经释放了该资源,这时就会出问题。因为对象x和y中的成员指针共享同一段内存,所以对y中的成员指针p的修改就会影响到对象x中的成员指针。所有这些情况都需要重定义复制构造函数来显示的初始化成员的值,这种初始化方式也被称为深度复制。
复制构造函数的使用
class hyong
{
public:
hyong();
hyong(int i);
hyong(const hyong& obj);
~hyong();
void h(hyong k);
hyong f();
int a,b,c;
};
hyong::hyong()
{
a=b=c=0;
cout<<"构造函数"<<"\n";
}
hyong::hyong(int i)
{
a=b=c=i;
cout<<"构造函数2"<<"\n";
}
hyong::~hyong()
{
cout<<"析构函数"<<"\n";
}
//复制构造函数
hyong::hyong(const hyong &obj)
{
a=obj.a;
b=obj.b;
c=obj.c;
cout<<"复制构造函数"<<"\n";
}
//按值传递对象
void hyong::h(hyong k)
{
cout<<"按值传递对象"<<k.a<<k.b<<"\n";
}
//返回值为对象
hyong hyong::f()
{
hyong kk(5);
return kk;
}
析构函数
1、不管类是否定义了自己的析构函数,编译器都自动执行类中非static数据成员的析构函数。
2、如果类需要析构函数,则他也需要赋值操作符和复制构造函数。,这个规则常称作三法则。
3、一般而言,析构函数可以执行任意操作,该操作时类设计者希望在该类对象的使用完毕之后执行的。
4、合成析构函数按对象创建时的逆序撤销每个非static成员。
5、合成析构函数并不删除指针成员所指向的对象。
6、析构函数没有返回值,没有形参。因为不能指定任何形参,所以不能重载析构函数。
7、即使我们编写了自己的析构函数,合成析构函数依然运行。
2、复制构造函数、赋值操作符、析构函数总称复制控制。编译器自动实现这些操作,蛋类也可以定义自己的版本。
3、有一种特别常见的情况需要类定义自己的复制控制成员的:类具有指针成员。
复制构造函数
1、是一种特殊的构造函数,具有单个形参,该形参(常用const修饰)是对该类类型的引用。
2、当形参或返回值为类类型时,有复制构造函数进行复制。
3、即使我们定义了其他构造函数,也会合成复制构造函数。,他的行为是,执行逐个成员初始化,将新对象初始化为原对象的副本。
4、为了防止复制,类必须显示声明其复制构造函数为private。
如果想要连友元和成员中的复制也禁止,就可以声明一个private复制构造函数但不对其定义。
5、声明而不定义成员函数式合法的,但是使用为定义成员的人和尝试将导致连接失败。
6、大多数类应定义复制构造函数和默认构造函数。
7、如果定义了复制构造函数,也必须定义默认构造函数。
复制构造函数以下部分来自百度百科:
何时使用复制构造函数:按值传递对象,函数返回对象,用一个对象初始化另一个对象(即复制初始化),根据元素初始化列表初始化数组元素,这四种情况都将调用复制构造函数。记住:复制构造函数只能用于初始化,不能用于赋值,赋值时不会调用复制构造函数,而是使用赋值操作符。
复制初始化与复制构造函数:复制初始化使用=等于符号来初始化,复制初始化也是创建一个新对象,并且其初值来自于另一个已存在的对象,复制初始化总是调用复制构造函数来初始化的。复制初始化时,首先使用指定的构造函数创建一个临时对象,然后用复制构造函数将临时对象的每个非static成员依次的复制到新创建的对象,复制构造函数执行的是逐个成员初始化。注意,这里是用一个已存在的对象创建另一个新对象,与用构造函数直接创建一个新对象不一样,使用构造函数初始化时不会使用另一个对象。比如有类hyong,则语句hyong
m(1,2)调用构造函数直接初始化,而语句hyong n=m则是用已存在的对象m去初始化一个新对象n,属于复制初始化。
理解赋值与复制初始化的区别(重点):赋值是在两个已存在的对象间进行的,也就是用一个已存在的对象去改变另一个已存在对象的值。赋值将调用赋值操作符对对象进行操作,赋值操作符将在操作符重载中讲解。比如有类hyong,有语句hyong x(1);hyong y(1,2)则x=y;这就是赋值,因为对象x和y是已经存在的对象,而语句hyong x=y;则是复制初始化,是用一个已存在的对象y去创建一个新对象x,所以是复制初始化。
复制初始化和赋值是在两个对象之间进行的操作,而直接初始化则不是
复制构造函数的形式:hyong(const hyong & obj);它接受一个指向类对象的常量引用作为参数。定义为const是必须的,因为复制构造函数只是复制对象,所以没必要改变传递来的对象的值,声明为引用可以节省时间,如果是按值传递的话就会生成对象的副本,会浪费资源,而引用就不会。
为什么需要定义自己的复制构造函数:如果类只包含类类型成员和内置类型的成员,则可以不用显示定义复制构造函数。但如果类中包含有指针或者有分配其他类型资源时,就必须重新定义复制构造函数。因为类中有指针成员,当把用一个对象初始化另一个对象时,这时两个对象中的指针都指向同一段内存,这时如果其中一个对象被消毁了,这时对象中指针所指向的内存也同样被消毁,但另一个对象确不知道这种情况,这时就会出现问题。比如hyong类中含有一个成员指针p,当声明了hyong x=y其中y也是hyong类的对象,这时对象x和y中的指针成员p都指向同一段内存,而如果y被消毁,但x还没被消毁时就会出问题,这时y中对象的成员指针p已经释放了该内存资源,而x中的成员指针p还不知道已经释放了该资源,这时就会出问题。因为对象x和y中的成员指针共享同一段内存,所以对y中的成员指针p的修改就会影响到对象x中的成员指针。所有这些情况都需要重定义复制构造函数来显示的初始化成员的值,这种初始化方式也被称为深度复制。
复制构造函数的使用
class hyong
{
public:
hyong();
hyong(int i);
hyong(const hyong& obj);
~hyong();
void h(hyong k);
hyong f();
int a,b,c;
};
hyong::hyong()
{
a=b=c=0;
cout<<"构造函数"<<"\n";
}
hyong::hyong(int i)
{
a=b=c=i;
cout<<"构造函数2"<<"\n";
}
hyong::~hyong()
{
cout<<"析构函数"<<"\n";
}
//复制构造函数
hyong::hyong(const hyong &obj)
{
a=obj.a;
b=obj.b;
c=obj.c;
cout<<"复制构造函数"<<"\n";
}
//按值传递对象
void hyong::h(hyong k)
{
cout<<"按值传递对象"<<k.a<<k.b<<"\n";
}
//返回值为对象
hyong hyong::f()
{
hyong kk(5);
return kk;
}
析构函数
1、不管类是否定义了自己的析构函数,编译器都自动执行类中非static数据成员的析构函数。
2、如果类需要析构函数,则他也需要赋值操作符和复制构造函数。,这个规则常称作三法则。
3、一般而言,析构函数可以执行任意操作,该操作时类设计者希望在该类对象的使用完毕之后执行的。
4、合成析构函数按对象创建时的逆序撤销每个非static成员。
5、合成析构函数并不删除指针成员所指向的对象。
6、析构函数没有返回值,没有形参。因为不能指定任何形参,所以不能重载析构函数。
7、即使我们编写了自己的析构函数,合成析构函数依然运行。
相关文章推荐
- 析构函数-复制构造函数-赋值操作符重载-默认构造函数<代码解析>
- C++在单继承、多继承、虚继承时,构造函数、复制构造函数、赋值操作符、析构函数的执行顺序和执行内容
- C++在单继承、多继承、虚继承时,构造函数、复制构造函数、赋值操作符、析构函数的执行顺序和执行内容
- 字符串类的实现:构造函数、析构函数、复制构造函数和赋值操作符
- 写一个类的构造函数、复制构造函数、析构函数、赋值函数
- 构造函数,析构函数,复制构造函数的理解
- C++在单继承、多继承、虚继承时,构造函数、复制构造函数、赋值操作符、析构函数的执行顺序和执行内容
- C++在单继承、多继承、虚继承时,构造函数、复制构造函数、赋值操作符、析构函数的执行顺序和执行内容
- C++ 第13章 复制控制---复制构造函数、赋值操作符、析构函数
- String的构造函数,析构函数,复制构造函数,赋值运算符
- 构造函数 复制构造函数 类型转换构造函数 析构函数
- C++在单继承、多继承、虚继承时,构造函数、复制构造函数、赋值操作符、析构函数的执行顺序和执行内容
- 第十二章-----第十三章 构造函数 复制构造函数 赋值操作符析构函数 static类成员
- 构造函数、复制构造函数、类型转换构造函数、析构函数
- 类中的构造函数,析构函数,复制构造函数,赋值函数
- 实例解说构造函数 复制构造函数 赋值运算符 析构函数
- 构造函数、复制构造函数、析构函数混合使用总结
- C++在单继承、多继承、虚继承时,构造函数、复制构造函数、赋值操作符、析构函数的执行顺序和执行内容
- C++在单继承、多继承、虚继承时,构造函数、复制构造函数、赋值操作符、析构函数的执行顺序和执行内容
- C++在单继承、多继承、虚继承时,构造函数、复制构造函数、赋值操作符、析构函数的执行顺序和执行内容 【转】 参考度4.6星