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

【继承关系中赋值运算符的重载、单例模式】

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

【继承关系中赋值运算符的重载、单例模式】

继承关系中赋值运算符的重载

1.程序设计者在基类和派生类中都没有重载operator=函数; C++编译器将在基类和派生类中自动产生按位赋值的,重载operator=函数;C++编译器会在派生类的重载赋值函数中,加入基类重载赋值函数的调用,是C++编译器合成的代码;(完成行为的统一);// 0 .

2.程序设计者在基类中定义重载赋值函数;而在派生类中没有定义重载赋值函数;C++编译器将会在派生类中自动产生按位赋值的重载赋值函数。并合成代码,调用(关联)基类的重载赋值函数。

class person {
private:

	string _name;
	int _age;
public:
	string _idperson;

	person& operator=(const person& s1)
	{
		_name = s1._name;
		_age = s1._age;
		_idperson = s1._idperson;
		return *this;
	}
	person(const string& idperson, const string& name, int x) : _idperson(idperson), _name(name), _age(x)
	{
		cout << " Create peron" << endl;
	}
};
class Student :public person
{
private:
	string _snum;
	float _score;
public:
	Student(const string& idperson, const string& name, int age, const char* ip) :person(idperson, name, age), _score(100)
	{
		_snum = name;

	}
};
int main()
{
	string name = "wang";
	string idperson{ "22000002" };
	Student stux(idperson, name, 12, "202201");
	Student stux1("931211","lmy",28,"00000");
	stux1 = stux;
	//stux.print();
	stux1.print();
}

3,程序设计者在基类和派生类中都定义了重载赋值函数;程序设计者在派生类中,没有指定调用基类的重载赋值函数时。C++编译器不会合成调用基类的重载赋值函数的代码。要在派生类的重载赋值函数调用基类的重载赋值函数,程序设计者必须自己加入调用代码。 1 1

class person {
private:

	string _name;
	int _age;
public:
	string _idperson;

	person& operator=(const person& s1)
	{
		_name = s1._name;
		_age = s1._age;
		_idperson = s1._idperson;
		return *this;
	}
	person(const string& idperson, const string& name, int x) : _idperson(idperson), _name(name), _age(x)
	{
		cout << " Create peron" << endl;
	}
};
class Student :public person
{
private:
	string _snum;
	float _score;
public:
	Student(const string& idperson, const string& name, int age, const char* ip) :person(idperson, name, age), _score(100)
	{
		_snum = name;

	}
	Student& operator=(const Student &s1)
	{
		_snum = s1._snum;
		_score = s1._score;
		return *this;
	}
};
int main()
{
	string name = "wang";
	string idperson{ "22000002" };
	Student stux(idperson, name, 12, "202201");
	Student stux1("931211","lmy",28,"00000");
	stux1 = stux;
	//stux.print();
	stux1.print();
}

没有调用基类的赋值重载,那么我们怎么能实现调用基类的赋值重载呢?
请看如下代码:

Student& operator=(const Student &s1)
	{
		_snum = s1._snum;
		_score = s1._score;
		person::operator=( s1);//调动基类的赋值语句
		return *this;
	}

4.程序设计者在基类中没有定义重载赋值函数(C++编译器将自动产生按位赋值的重载赋值函数)。而在派生类中定义了重载赋值函数。程序设计者在派生类中,没有指定调用基类的重载赋值函数。C++编译器不会合成调用基类的重载赋值函数的代码。

class person {
private:

	string _name;
	int _age;
public:
	string _idperson;
	person(const string& idperson, const string& name, int x) : _idperson(idperson), _name(name), _age(x)
	{
		cout << " Create peron" << endl;
	}
};
class Student :public person
{
private:
	string _snum;
	float _score;
public:
	Student(const string& idperson, const string& name, int age, const char* ip) :person(idperson, name, age), _score(100)
	{
		_snum = name;
	}
	Student& operator=(const Student &s1)
	{
		_snum = s1._snum;
		_score = s1._score;
		//person::operator=( s1);//调动基类的赋值语句
		return *this;
	}
};
int main()
{
	string name = "wang";
	string idperson{ "22000002" };
	Student stux(idperson, name, 12, "202201");
	Student stux1("931211","lmy",28,"00000");
	stux1 = stux;
	//stux.print();
	stux1.print();
}

//student赋值函数加上这行代码:
		person::operator=( s1);//调动基类的赋值语句
	}

delete删除关键字用在构造函数上的情况
protected:
	
	lmy(const string& name, const string& sex, int age)  : _name(name), _sex(sex), _age(age) {}
	~lmy() {}
	lmy(const lmy& s1) = delete;//将拷贝构造删除
	lmy& operator=(const lmy& s1) = delete;
	

如果基类的拷贝构造和赋值函数都删除,确在派生类中定义了拷贝和赋值函数,则基类的删除不起作用。

几种域,在类的访问时的一些情况:


块域:比如if(){}里的内容属于块域。

单例模式

单例模式,属于创建类型的一种常用的软件设计模式。通过单例模式的方法创建的类在当前进程中只有一个实例(根据需要,也有可能一个线程中属于单例,如:仅线程上下文内使用同一个实例)

第一种单例模式(也是饥汉模式):

using namespace std;
#if 1
class lmy 
{
private:
	string _name;
	string _sex;
	int _age;
public:
	void fun()
	{
		cout << " lmy unique plays  " << endl;
		//_name = "gouzi09";
		cout << "  name =  "<<_name << endl;
	}
protected:
	
	lmy(const string& name, const string& sex, int age)  : _name(name), _sex(sex), _age(age) {}
	~lmy() {}
	lmy(const lmy& s1) = delete;
	//lmy(const lmy& s1) :_name(s1._name), _sex(s1._sex), _age(s1._age) {} 
	lmy& operator=(const lmy& s1) = delete;
	
private:
	static lmy lmy1;
public:
	static lmy& get_single()
	{
		return  lmy1;
	}
};
lmy lmy::lmy1("gouzi2", "man_or_woman", 1);
class llmy :private lmy
{
private:
	string _name;
	string _sex;
	int _age;
public:
	void fun()
	{
		cout << " llmy unique plays  " << endl;
		//lmy::fun();
	}
private:
	
	
	llmy(const string& name, const string& sex, int age) :lmy(name,sex,age),_name(name), _sex(sex), _age(age) {}
	~llmy() {}
	llmy(const llmy& s1)  = delete;
	
	llmy& operator=(const llmy& s1) = delete;
	
private:
	static llmy l1;
public:
	static llmy& get_single()
	{
		return  l1;
	}
};
llmy llmy::l1("gouzi2", "man_or_woman", 1);
int main()
{
	llmy& l1 = llmy::get_single();
	//llmy s1;
	l1.fun();
	lmy& lmy1 = lmy::get_single();
	lmy1.fun();
	//lmy lmy2("gouzi2", "man_or_woman", 1);
	return 0;
}

我们用static 关键字加上私有的构造函数做出了只能构造一个的对像,则称为单例模式。

如果基类的构造函数属性是私有的 ,那么 派生来的单例模式此时无法生成,所以我们可以利用继承特性将其设置成保护:


第二种:饿汉模式:实例在使用之前就已经创建。

class lmy 
{
private:
	string _name;
	string _sex;
	int _age;
public:
protected:
	lmy(const string& name, const string& sex, int age)  : _name(name), _sex(sex), _age(age) {}
	~lmy() {}
	lmy(const lmy& s1) = delete;
	//lmy(const lmy& s1) :_name(s1._name), _sex(s1._sex), _age(s1._age) {} 
	lmy& operator=(const lmy& s1) = delete;
	
private:
	static lmy lmy1;
public:
	static lmy& get_single()
	{
		return  lmy1;
	}
};
lmy lmy::lmy1("gouzi2", "man_or_woman", 1);
class llmy :private  lmy
{
private:
	string _name;
	string _sex;
	int _age;
public:
public:
	llmy(const string& name, const string& sex, int age) :lmy(name,sex,age),_name(name), _sex(sex), _age(age) {}
	~llmy() {}
	llmy(const llmy& s1)  = delete;
	
	llmy& operator=(const llmy& s1) = delete;
public:
	static llmy& get_single()
	{
		static llmy l1("gouzi2", "man_or_woman", 1);
		return l1;
	}
};
int main()
{
	llmy& l1 = llmy::get_single();
	l1.fun();
	lmy &lmy1 = lmy::get_single();
	return 0;
}

第三种:懒汉模式:实例在使用时才创建。

class lmy 
{
private:
	string _name;
	string _sex;
	int _age;
public:

protected:
	
	lmy(const string& name, const string& sex, int age)  : _name(name), _sex(sex), _age(age) {}
	~lmy() {}
	lmy(const lmy& s1) = delete;
	//lmy(const lmy& s1) :_name(s1._name), _sex(s1._sex), _age(s1._age) {} 
	lmy& operator=(const lmy& s1) = delete;
	
private:
	static lmy lmy1;
public:
	static lmy& get_single()
	{
		return  lmy1;
	}
};
lmy lmy::lmy1("gouzi2", "man_or_woman", 1);
class llmy :private  lmy
{
private:
	string _name;
	string _sex;
	int _age;
public:
public:
	llmy(const string& name, const string& sex, int age) :lmy(name,sex,age),_name(name), _sex(sex), _age(age) {}
	~llmy() {}
	llmy(const llmy& s1)  = delete;
	llmy& operator=(const llmy& s1) = delete;
private :
	static llmy* p;
public:
	static llmy& get_single()
	{
		if (p == nullptr)
		{
			p = new llmy("gouzi2", "man_or_woman", 1);//new 了一个新对象
		}
		return *p;
	}
};
llmy* llmy:: p = nullptr;//注意:llmy* (类型指针)llmy:: (加标识)p(指针变量)
int main()
{
	llmy& l1 = llmy::get_single();
	l1.fun();
	lmy &lmy1 = lmy::get_single();
	lmy1.fun();
	return 0;
}


单例模式在多进程和多线程时可能会发生线程安全的问题。

暑期编程PK赛 得CSDN机械键盘等精美礼品!
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1015958.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

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

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