C++学习:第三章C++语言基础 - (六)构造、析构、IO、运算符重载

本文深入探讨C++中的构造函数与析构函数特性,包括new创建对象的方法、内存分配与释放、数组形式的new类创建与delete释放、声明函数末尾加const的用法、对象作为函数传参时的构造与析构情况、类似数组访问传参的可变常量问题及IO运算符定义。

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

1. 构造函数

析构函数特点:

  1. 对象释放时调用
  2. 只能调用一次
  3. 用来释放内存等工作
  4. 析构函数总数五参的,所以不可以重载

2. 对象的new创建方法

#include <iostream>
using namespace std;

class F{
	int n;
	int d;
	int f;
public:
	F(int n = 0, int d = 1);
	~F();//析构函数,自动调用。
	void print(bool newLine = true);
	void input();
};

//几种初始化方法
F::F(int n, int d){
	F::n = n;
	this->d = d;
	(*this).f = 0;
}

F::~F(){
	cout << "调用析构函数" << endl; }


int main(){
	
	F* f = new F(3,3);
	delete f;
	f = NULL;

	getchar();
	return 0;
}

new创建对象的特点:

  1. new创建类对象需要指针接收,一处初始化,多处使用
  2. new创建类对象使用完需delete销毁
  3. new Class[4]创建的对象需要delete[] class销毁。
  4. new创建对象直接使用堆空间,而局部不用new定义类对象则使用栈空间
  5. new对象指针用途广泛,比如作为函数返回值、函数参数等
  6. 频繁调用场合并不适合new,就像new申请和释放内存一样
  7. 用new创建的对象可以用delete删除,同时会调用该类的析构函数,如果是用C语言风格分配的内存则不会调用析构函数

3. C++中的内存分配与释放

C++中分配动态内存推荐用new,不推荐用malloc,因为malloc是C语言的

int* a;
a = new int[7];

for(int i=0; i<7; i++){
	a[i] = 100+i;
	cout << a[i] << endl;
}

delete a;
a = NULL;

 

4. 数组形式的new类创建与delete释放(构造函数与析构函数的调用情况和数组)

#include <iostream>
#include <string>
using namespace std;

class F{
	int n;
	int d;
	int f;
public:
	F(int n = 0, int d = 1);
	~F();//析构函数,自动调用。
	void print(bool newLine = true);
	void input();
};


//几种初始化方法
F::F(int n, int d){
	F::n = n;
	this->d = d;
	(*this).f = 0;
	cout << "调用构造函数, n = " << n << "; d = " << d <<endl;  
}


F::~F(){
	cout << "调用析构函数, n = " << n << "; d = " << d <<endl; 
}


int main(){
	cout << "F* q = static_cast<F*>(malloc(sizeof(F)));" << endl;
	F* q = static_cast<F*>(malloc(sizeof(F)));
	free(q);

	cout << endl << endl << "F* p = new F;" << endl;
	F* p = new F;
	delete p;
	p = NULL;

	//数组形式的创建与释放
	cout << endl << endl << "q = new F[4];" << endl;
	q = new F[4];
	for(int i=0; i<4; i++){
		cout << "q[" << i << "]" << endl;
	}
	delete[] q;
	
	getchar();
	return 0;
}

5. 声明函数末尾加 const 的用法

    1. 说明该函数对当前对象的操作是只读的
    2. 函数调用时默认调用不带const的方法
    3. 如果用const初始化对象会默认调用带const的方法

#include <iostream>
#include <string>
using namespace std;

class F{
    int n;
    int d;
    int f;
    public:
    F(int n = 0, int d = 1);
    ~F();//析构函数,自动调用。
    void print(bool newLine = true);
/*
    此处const的说明
    1. 说明该函数对当前对象的操作是只读的
    2. 函数调用时默认调用不带const的方法
    3. 如果用const初始化对象会默认调用带const的方法
*/
    void print(bool newLine = true)const;
    void input();
};

//几种初始化方法
F::F(int n, int d){
    F::n = n;
    this->d = d;
    (*this).f = 0;
    cout << "调用构造函数, n = " << n << "; d = " << d <<endl;  
}

F::~F(){
    cout << "调用析构函数, n = " << n << "; d = " << d <<endl;  
}


int main(){
    cout << "F* q = static_cast<F*>(malloc(sizeof(F)));" << endl;
    F* q = static_cast<F*>(malloc(sizeof(F)));
    free(q);

    cout << endl << endl << "F* p = new F;" << endl;
    F* p = new F;
    delete p;
    p = NULL;

    cout << endl << endl << "q = new F[4];" << endl;
    q = new F[4];
    for(int i=0; i<4; i++){
        cout << "q[" << i << "]" << endl;
    }
    delete[] q;

    getchar();
    return 0;
}

 

6. 对象在作为函数传参时的构造与析构情况

#include <iostream>
#include <string>
using namespace std;

class F{
    int n;
    int d;
    int f;
public:
    F(int n = 0, int d = 1);
    F(const F& f);//如果没写编译器会自动完成
    ~F();//析构函数,自动调用。
    void print(bool newLine = true);
    void print(bool newLine = true)const;
    void input();
};

//几种初始化方法
F::F(int n, int d){
    F::n = n;
    this->d = d;
    (*this).f = 0;
    cout << "调用构造函数, this = " << this << "; d = " << d <<endl;  
}

F::F(const F& f){
    this->n = f.n;//传参用;
    this->d = f.d;
    cout << "调用构造函数, this = " << this << "; d = " << d <<endl;
}

F::~F(){
    cout << "调用析构函数, this = " << this << "; d = " << d <<endl;  
}

F func(F f){
    return f;
}


F& func2(F& f){
    return f;
}

/*
    结果说明:
    1. 结果中会有三个析构函数,这是因为对象被创建了三次:F f(20, 50)、func(f)、return f
        这三次分别是类初始化、实参-形参、return返回值
    2. 为了说明被创建了三次,特意写了函数 F(const F& f);
    3. 改为引用则不会有上诉问题,见 func2
*/

int main(){
    F f(20, 50);
    cout << "=======================================" << endl ;
    func(f);
    cout << "=======================================" << endl << endl ;

    cout << "---------------------------------------" << endl ;
    func2(f);
    cout << "---------------------------------------" << endl << endl ;

    getchar();
    return 0;
}

 

7. 类似数组访问传参的可变常量问题

mutable 修饰可修改的常量

#include <iostream>
using namespace std;

class Aarray{
    char a[100];
    int len;
    mutable int cur;
public:
    void first()const{cur = -1;};
    char next()const{return a[++cur];};
    bool hasnext()const{return cur<=(len-1);};
    void add(char c);
    void add(const char* s){
        while(*s){
            add(*s++);
        }
    }
    void remove(int pos);
    Aarray():len(0),cur(0){};
    void p(){
        cout << "This is Aarray : ";
        first();
        while(hasnext()){
            cout << next();
        }
        cout << endl << endl;
    }
};

void Aarray::add(char c){
    a[len++] = c;}

void Aarray::remove(int pos){
    if (len<0 || pos>=len){
    return; }
    while(pos<len){
        a[pos] = a[pos+1];
        pos ++;
    }
    --len;
}

int main(){
 
    Aarray a;
    a.add("abcdefghijklmnopqrstuvwxyz");
    a.p();

    getchar();
    return 0;
}

8. IO :   >> 运算符定义

  1. C++中的cin 和 cout 是通过一系列的函数重载定义完成的
  2. 内部类似istream& operator>>(istream& cin, F& f){ cin >> n;} 的写法实现的
  3. 调用时候系统会先调用cin.operator>>(n);再调用operator>>(cin, n)。也就是说,当我们自己实现该方法时两个方式只实现一个即可,两个都实现会有调用问题
#include <iostream>
using namespace std;

class F{
    int n;
    int d;
public:
    F(int n=0, int d=1):n(n),d(d){};
    void print(bool newline = true);
    void input();
    //friend 该关键字指定类中访问私有变量
    friend istream& operator>>(istream& cin, F& f);
    friend ostream& operator<<(ostream& cout, const F& f);
};


//operator关键字可以定义运算符
istream& operator>>(istream& cin, F& f){
    char c;
    cin >> f.n >> c >> f.d;
    return cin;
}

ostream& operator<<(ostream& cout, const F& f){
    cout << f.n << '/' << f.d << endl;
    return cout;
}

int main(){

    F a,b;
    cin >> a;
    cout << a;

    getchar();
    return 0;
}
F a, b,c;

c = a+b;

//实现方法:

1. a.operator+(F b){}//看成第一个类的成员函数

2. operator(F a, F b){}//看成一个普通方法

两个实现方法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值