0
点赞
收藏
分享

微信扫一扫

C++常见异常解决方案大全

二义性

通过virtual关键字实现虚继承,可以解决多重继承造成的二义性问题

#include <iostream>
using namespace std;

class Animal {
public:
	int m_Age;
};

class Lion : public Animal {};
class Tiger : public Animal {};
class LionTiger : public Lion, public Tiger {};

class LionV : virtual public Animal {};
class TigerV : virtual public Animal {};
class LionTigerV : public LionV, public TigerV {};

void test() {
	LionTiger lt; // LionTiger 一个对象有两份年龄,不合常理
	lt.Lion::m_Age = 1;
	lt.Tiger::m_Age = 2;
	cout << lt.Lion::m_Age << endl;
	cout << lt.Tiger::m_Age << endl;
	// cout << lt.m_Age << endl; // 强行把两份年龄当成一份去使用,就会引发二义性
	
	LionTigerV ltv; // LionTigerV 一个对象有一份年龄,非常合理
	ltv.m_Age = 3;
	cout << ltv.m_Age << endl;
}

int main() {
	test();
	return 0;
}

二次析构

通过深拷贝解决二次析构问题

#include <iostream>
using namespace std;

class Person {
public:
	Person(int age, int height) {	
		m_age = age;
		m_height = new int(height);
	}
	Person(const Person& p) {
		m_age = p.m_age;
		m_height = new int(*p.m_height); // 深拷贝,p1 p2 两个对象的 m_height 指针不会指向堆区的同一块内存
	}
	~Person() {
		if (nullptr != m_height) {
			cout << "delete addr " << m_height << endl;
			delete m_height;  // 两次析构,不会重复释放堆区的同一块内存
		}
	}
private:
	int m_age;
	int* m_height;
};

void test() {
	Person p1(18, 180);
	Person p2(p1);
}

int main() {
	test();
	return 0;
}

内存溢出

使用安全函数解决内存溢出问题

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

int test() {
	// 测试环境:小端机,栈上变量自高地址向低地址生长
	char buf1[4];
	char buf2[4];
	char buf3[4];
	strcpy(buf2, "BBBB");
	strcpy(buf3, "CCCC");
	cout << buf2 << endl; // buf2 的 '\0' 被 buf3 覆盖了
	strcpy(buf1, "AAAA");
	cout << buf2 << endl; // buf2 的首地址被 '\0' 覆盖了
	return 0;
}

int main() {
	test();
	return 0;
}

子类内存泄漏

通过虚继承解决子类内存泄漏问题

#include <iostream>
using namespace std;

class Dad {
public:
    ~Dad() { cout << "Dad::destrutor" << endl; }
};

class Son : public Dad {
public:
    ~Son() { cout << "Son::destrutor" << endl; }
};

class Dad2 {
public:
    virtual ~Dad2() { cout << "Dad2::destrutor" << endl; } // 虚析构
};

class Son2 : public Dad2 {
public:
    ~Son2() { cout << "Son2::destrutor" << endl; }
};

int main()
{
    Dad* p = new Son;
    delete p; // 从打印结果可以看出,子类 Son 的析构函数没有被调用
	cout << endl;
	Dad2* q = new Son2;
    delete q;
    return 0;
}

整型溢出

通过位运算解决整型溢出问题

#include <iostream>
using namespace std;

int main() {
    int l = 2147483644, r = 2147483646;
    int m1 = l + ((r - l) >> 1);
    cout << "correct mid: " << m1 << endl;
    int m2 = (l + r) / 2;
    cout << "wrong mid: " << m2 << endl;
    return 0;
}

访问非法内存

通过静态扫描工具,可以有效避免访问非法内存

#include <iostream>
using namespace std;

class Person {
public:
	Person() {
		var_ = 0;
	}
	void func_1() {
        	cout << "func_1" << endl;
	}
    void func_2() {
		cout << var_ << endl;
		cout << "func_2" << endl;
	}
	virtual void func_3() {};
private:
	int var_;
};

void test() {
	Person *p = nullptr;
	cout << p << endl; // 不会报错:因为空指针在内存里地址是0
	p->func_1(); // 不会报错:
	p->func_2(); // 会报错:访问了成员变量,地址不存在
	p->func_3(); // 会报错:访问了虚指针,地址不存在
}

int main() {
	test();
	return 0;
}
举报

相关推荐

0 条评论