栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C++:继承和派生

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C++:继承和派生

1. 讨论公有继承:“是一个”

派生类与基类:
赋值兼容规则
C++面向对象编程中一条重要的规则是:公有继承意味着“是一个”。
在任何需要基类对象的地方都可以用公有派生类的对象来代替,这条规则称赋值兼容规则,它包括以下几种情况:
1. 派生类的对象可以赋值给基类的对象,这时是把派生类对象中从对应基类中继承来的隐藏对象赋值给基类对象。反过来不行,因为派生类的新成员无值可赋;
2. 可以将一个派生类的对象的地址赋给其基类的指针变量,但只能通过这个指针访问派生类中由基类继承来的隐藏对象,不能访问派生类中的新成员。同样反过来也不行。
3. 派生类对象可以初始化基类的引用。引用是别名,但这个别名只能包含派生类对象中的由基类继承来的隐藏对象 。

#include 
#include
#include
#include
#include
using namespace std;


class object
{
public:
	int value;
public:
	object(int x=0):value(x) {}
	~object() {}
	void print(int x)
	{
		value = x;
		cout << value << endl;
	}
};
class Base :public object
{
public:
	int num;
public:
	Base(int x=0):object(x),num(x+10) {}
};

int main()
{
	Base base(10);
	object obja(0);
	object* op = &base;
	object& ob = base;
	obja = base;
	return 0;
}

2. 继承中的构造函数与析构函数

公有继承中派生类型对象构造和析构

 
#include
#include
#include
#include
using namespace std;

class Person
{
	int _id;
public:
	Person(int id) :_id(id)
	{
		cout << "Create Person " << this << endl;
	}
	~Person()
	{
		cout << "Destroy Person " << this << endl;
	}
};
class Trans
{
	int c_num;
public:
	Trans(int num) :c_num(num)
	{
		cout << "Create Trans " << this << endl;
	}
	~Trans()
	{
		cout << "Destroy Trans " << this << endl;
	}
};
class Student : public Person
{
	int _s_id;
	Trans table;
public:
	Student(int id, int s, int n) :_s_id(s), table(n), Person(id)
	{
		cout << "Create Student " << this << endl;
	}
};
int main()
{
	Student stud(90010, 202201, 23);
	return 0;
}

运行结果:
构造函数基础:

#include 
#include
#include
#include
#include
using namespace std;

class object
{
private:
	int value;
public:
	object(int x = 0) :value(x)
	{
		cout << "Create object:" << this << endl;
	}
	object(const object& obj) :value(obj.value)
	{
		cout << "copy Create object:" << this << endl;
	}
	object& operator=(const object& obj)
	{
		if (this != &obj)
		{
			value = obj.value;
		}
		cout << "object::operator=" << endl;
		return *this;
	}
	~object() { cout << "Destroy object:" << this << endl; }
};
class Base :public object
{
private:
	int num;
public:
	Base(int x = 0)
		:object(x), num(x + 10)
	{
		cout << "Create Base: " << this << endl;
	}
	~Base()
	{
		cout << "Destroy Base: " << this << endl;
	}
};
int main()
{
	Base base1(10);
	Base base2(base1);
	Base base3(30);
	base1 = base3;
	return 0;
}

运行结果:

继承关系中拷贝构造函数
  1. 程序设计者在基类和派生类中都没有定义拷贝构造函数;C++编译器将自动产生按位拷贝的拷贝构造函数;在派生类的拷贝构造函数的初始化表中,加入基类拷贝构造函数的调用,是C++编译器合成的代码;(完成行为的统一);0/0
  2. 程序设计者在基类中定义拷贝构造函数;而在派生类中没有定义拷贝构造函数;C++编译器将会在派生类中自动产生按位拷贝的拷贝构造函数。并合成代码,调用(关联)基类的拷贝构造函数。l/ 0
  3. 程序设计者在基类和派生类中都定义了拷贝构造函数;程序设计者在派生类中,没有指定调用基类的拷贝构造函数时。C++编译器合成的代码调用基类的缺省构造函数,如果基类中没有缺省构造函数。合成代码失败。编译错误。1/1
  4. 程序设计者在基类中没有定义拷贝构造函数(C++编译器将自动产生按位拷贝的拷贝构造函数)。而在派生类中定义了拷贝构造函数。程序设计者在派生类中,没有指定调用基类的拷贝构造函数时。C++编译器合成的代码调用基类的缺省构造函数,如果基类中没有缺省构造函数。0/1
继承关系中赋值运算符的重载
  1. 程序设计者在基类和派生类中都没有重载operator=函数;C++编译器将在基类和派生类中自动产生按位赋值的,重载operator=函数;C++编译器会在派生类的重载赋值函数中,加入基类重载赋值函数的调用,是C++编译器合成的代码;(完成行为的统一);0/0
  2. 程序设计者在基类中定义重载赋值函数;而在派生类中没有定义重载赋值函数;C++编译器将会在派生类中自动产生按位赋值的重载赋值函数。并合成代码,调用(关联)基类的重载赋值函数。l/ 0
  3. 程序设计者在基类和派生类中都定义了重载赋值函数;程序设计者在派生类中,没有指定调用基类的重载赋值函数时。C++编译器不会合成调用基类的重载赋值函数的代码。要在派生类的重载赋值函数调用基类的重载赋值函数,程序设计者必须自己加入调用代码。1/1
  4. 程序设计者在基类中没有定义重载赋值函数(C++编译器将自动产生按位赋值的重载赋值函数)。而在派生类中定义了重载赋值函数。程序设计者在派生类中,没有指定调用基类的重载赋值函数。C++编译器不会合成调用基类的重载赋值函数的代码。0/1
    面试题:
    1 . 设计一个类型,不能在外部环境中创建该类的对象:
#include 
#include
#include
#include
#include
using namespace std;

class Singleton
{
	int value;
private:
	Singleton(int x=0): value(x) {}
public:
	Singleton(const Singleton&) = delete;//c98
	Singleton& operator=(const Singleton&) = delete;

private:
	~Singleton() { cout << "~Singleton " << endl; }
public:
	static Singleton& getinstance()
	{
		static Singleton s(10);
		return s;
	}
};

2. 设计一个不能被继承的类;(将其构造函数定义成私有)

#include 
#include
#include
#include
#include
using namespace std;

class non_herit
{
private:
	non_herit() {}
public:
	non_herit(const non_herit&) {}
	~non_herit() {}
};

3. 设计一个不能被继承的类,但可以在外部环境创建该类型的对象:(加入关键final)

#include 
#include
#include
#include
#include
using namespace std;

class non_herit final:public object
{
	int value;
public:
	non_herit(int x=0):value(x) {}
	non_herit(const non_herit&) = default;
	non_herit& operator=(const non_herit&) = default;
	~non_herit() = default;
};

4. 设计一个能被继承的类,但不可以在外部环境创建该类型的对象:

#include 
#include
#include
#include
#include
using namespace std;
class object
{
private:
	int value;
protected:
	object(int x=0):value(x) {}
	object(const object& obj):value(obj.value) {}
	object& operator=(const object& obj)
	{
		if (this != &obj)
		{
			value = obj.value;
		}
		return *this;
	}
public:
	~object();
};
class Base:public object
{
     int num;
 public:
     Base(int x=0):object(x+10),num(x) {}
};
int main()
{
   Base base(10); //ok
   object obj(20);//error
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1009108.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号