c++

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/p/3008918.html