2013.8.25补充
1、没有进行初始化的实例变量的值是任意的,例如:
class A
{
public:
int a;
};
A a;
count << a.a << endl; // 如果是a定义在全局范围内,则基本数据类型的数据成员初始化为0,如果定义在局部范围内,则值是随机的。
2、赋值运算符“=”,并不是构造函数,有些书上把它叫做赋值构造函数,这是不好的。当我们没有重载赋值运算符的时候,编译器会自动加入一个默认的运算符函数,当类中没有动态分配存储空间的变量和指针变量的时候,这个默认的赋值运算符函数能够满足我们的要求,但是,当类中有动态分配存储空间的变量和指针变量的时候,我们必须重写赋值运算符。
3、当我们的类中没有重载拷贝构造函数的时候,编译器也会给我们加入一个默认的拷贝构造函数,与赋值运算符一样,我们的类中有动态分配存储空间的变量和指针变量的时候,我们必须重写赋值运算符。
4、默认的不带任何参数的构造函数
class A
{
public:
int a;
};
例如上面的A类,当类中没有显示声明任何构造函数的时候(包括赋值构造函数,不包括赋值运算符,因为它根本不是构造哈数),编译器会自动加入一个不带任何参数的构造函数,但它什么也没做,没有对实例变量进行初始化。
当我们的类中显示声明任何一个构造函数的时候(包括赋值构造函数,不包括赋值运算符,因为它根本不是构造哈数),该没有任何参数的默认构造函数就不会被编译器自动加入了。
5、const是可以用来进行函数重载的,例如void a(int a); void a(const int a)是两个不同的函数,函数返回值不作为函数重载的依据。
6、对于类A来说, A(const A &a)和 A(A &a)都是它的拷贝构造函数,当我们在类A中没有声明这两个函数时,编译器会自动加入A(const A &a),因为const有很多好处,可以防止传入的A的对象被修改,还可以接受const和非const变量的参数。当我们在类中声明A(A &a)的时候,编译器就不会加入A(const A &a)这个拷贝构造函数
const A a;
A b(a);
A b = a; // 等价于A b(a); 都会调用 A(const A &a);
就会报错,因为它们寻找的是A(const A &a)这个函数,然而它并不存在,赋值运算符的情况与它相同
7、
A d; 调用A();
const A a; 调用 A();
A b; 调用 A();
b = a; 类A中如果存在 A& operator=(const A&),则调用;如果不存在,则报错
b = d; 类A中如果存在 A& operator=(A &),则调用;如果不存在,则调用A& operator=(const A&),此时A& operator=(const A&)是一定存在的,因为我们没有声明A& operator=(A &),如果我们再没有重写A& operator=(const A&),编译器会自动加入,如果我们重写啦,那它当然存在了。
8、 A(int a)和A(int &a)属于函数重载,因为它们同时存在时是合法的,只要不发生对它们的调用都是正确的,但是
int c;
c=10;
A(c);这时就会发生调用二义性
------------------------------------------------------------------------------------------------------
#include<iostream>
using namespace std;
class A
{
public:
A(); //如果不定义任何构造函数,系统会自动添加该没有任何参数的构造函数
A(int b);
A(int &b);
A(const A &b); //如果不定义该构造函数,系统会自动添加
//A(A b); 这样定义发生错误,参数不能只包含A类的变量,因为这样会造成构造函数的无限循环
//A(const A b); 同上
A(A b, int a);
int a;
};
A::A()
{
a = 10;
}
A::A(int b)
{
a = b;
}
A::A(int &b)
{
a = b;
}
A::A(const A &c)
{
a = c.a;
cout << "copy constructor" << endl;
}
void show(A a)
{
cout << a.a << endl;
}
void show(A &a)
{
cout << a.a << endl;
}
int main(void)
{
A a1; //调用A();
A a2(a1); //调用A(const A &b);
//int c=10;
//A a(c); 错误:A(int b)和A(int &b)出现二义性
A a3(10); //调用A(int b); 引用是对变量的引用,而10是常量,所以只会调用 A(int b);
//对于上面定义的void show(A a)和void show(A &a),如果main函数里面没有发生调用,它不会出现编译错误
//如果出现了调用 show(a1),则发生编译错误,这时void show(A a)和void show(A &a)不能共存,
//如果留下void show(A a),则在调用show(a1)的过程中,实参传递给形参的时候,调用A(const A &b);
//如果留下void show(A &a),则在调用show(a1)的过程中,实参传递给形参的时候,没有调用A(const A &b);
return 0;
}
原文链接: https://www.cnblogs.com/zzj2/archive/2013/04/08/3008918.html
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/83669
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!