类型转换运算符、初始化列表的初始化顺序、构造函数、拷贝构造函数、赋值语句、创建子类对象、数组指针

本文探讨了C++中的类型转换运算符,强调了在何种情况下必须使用初始化列表,并详细解释了初始化列表的顺序规则。同时,文章还涵盖了构造函数、拷贝构造函数和赋值语句的区别,以及创建子类对象时父类构造函数的调用过程。最后,提到了数组指针的使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

类型转换运算符

  • operator T() {} 返回值和T相同, 因此省略, 用来进行一些自定义数据的类型转换.
  • 为了避免歧义, T中不能有还有一个参数的构造函数, 否则T() 不知道是进行类型转换, 还是进行实例化.
#include <iostream>
using namespace std;

class Test1 {
public:
    int y;
public:
    Test1(){}
    Test1(int x, int y) {
        this->y = x;
    }
};

class Test2 {
    int x;
    Test1 t1;
public:
    Test2(int val) {
        x = val;
        t1 = Test1(val, val);
    }
    operator Test1() {return t1;}
    operator int() {return x;}
};

int main() {
    Test2 t(2);
    cout<<t.operator int()<<endl;
    cout<<int(t)<<endl;
    cout<<typeid(Test1(t)).name()<<endl;
    cout<<t.operator Test1().y<<endl;
    return 0;
}

初始化列表的初始化顺序

  • 初始化列表先于构造函数体执行
  • 成员的初始化顺序和成员的声明顺序相同.
  • 成员的初始化顺序和初始化列表中的位置无关.
  • 下面的例子中, 成员声明顺序是先x后y, 因此即使初始化列表的顺序写的是先y后x, 初始化的时候也是先初始化x, 此时y没有被初始化, 因此是个随机值, 之后再用a初始化y.
class A{
public:
	int x;
	int y;
	A(int a) : y(a), x(y){}
};

构造函数、拷贝构造函数、赋值语句

  • 拷贝构造函数 : 根据一个对象从无到有创建一个新对象
  • 赋值语句 : 已经有了一个对象, 根据另一个对象改变这个对象
class A{
public:
    A();                                    //默认构造
    A( A& a );                              //copy构造
    const A& operator=( const A& a );       //赋值操作符
};

A a;		// 默认构造函数
A a1(a);	// 拷贝构造函数
A a2 = a;	// 拷贝构造函数. 
			// 如果是赋值操作符, 需要先调用默认构造函数创建一个a2, 然后调用a2 = a 明显麻烦了. 
a1 = a2;	// 赋值操作符

};

必须使用初始化列表的情况

初始化列表调用的是拷贝构造函数

  • 非静态常量必须在初始化列表中初始化 (静态数据成员需要在类外初始化)

  • 引用成员必须在初始化列表中初始化

  • 没有默认构造函数的数据成员 (只能拷贝构造函数进行)

  • 基类数据成员的初始化
    必须使用初始化列表的情况

  • 这个构造函数为什么调用有点看不懂??????

class B {
public:
    int x;
    B(){cout<<"构造函数"<<endl;}
    B(B a) {cout<<"拷贝构造函数"<<endl;}
    B& operator=(const B& a) {
        cout<<"赋值操作"<<endl;
        return *this;
    }
};

class D{
public:
    B b;
    D(B& b){
        cout<<"===="<<endl;
        this->b = b;
        cout<<"gouzaohanshu"<<endl;
    }
};
int main() {
    B b;
    D d(b);
    return 0;
}
构造函数
拷贝构造函数	// 因为值传递是拷贝一份进行参数传递
构造函数		// 这个构造函数为什么调用有点看不懂??????
====
赋值操作
gouzaohanshu
Program ended with exit code: 0

创建子类对象

  • 创建子类对象, 首先调用的是父类的构造函数, 这个时候进入了父类对象,调用的函数自然是父类的.
class Base{
public:
    Base(){fun();}
    virtual void fun() {
        cout<<"\nBase function"<<endl;
    }
    
};

class Deri:public Base{
public:
    Deri(){}
    virtual void fun() {
        cout<<"\nDeri function"<<endl;
    }
};

void test03() {
    Base* base = new Deri();
    delete base;
}

Base function

数组指针

int p[10][20];
int (*pp)[10][20];
cout<<sizeof(*p)<<endl;  // p是二维数组的数组名, *p指向的是数组的第一个元素(一个长度为20的数组) 80
cout<<sizeof(*pp)<<endl; //pp是一个二维数组指针, *pp指向这个而为数组整体, 800
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值