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/archive/2013/04/08/3008918.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/83669

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月9日 下午9:12
下一篇 2023年2月9日 下午9:12

相关推荐