C++-详解class成员,构造,复制构造,析构函数,public,private,protect,内部类,static,this,friend,菱形继承

class其实就是struct的升级版,在java中已经删除了struct,全面改用class
class由包括成员函数和成员变量两种属性组成,成员函数又包括自定义函数和必须有的构造函数和析构函数,其中构造函数又包括默认无参的默认构造函数,自定义的构造函数(重载特色),以及复制构造函数,并且复制构造函数如果没有自定义,系统也会生成默认的复制构造函数。注意默认的复制构造函数是浅拷贝。也就是说b复制a,c也复制a…b,c…实际上是同一块内存,如果a是动态对象,释放后后面的复制对象内存就会崩溃,所以我们要自己手写一份深拷贝构造函数
class

class MyClass
{
public:
	int a, b;
	MyClass();//默认构造
	MyClass(int, int);//自定义构造
	MyClass(const MyClass& m);//自定义复制构造函数
	~MyClass();
private:
	
};
MyClass::MyClass()	
{
	cout << "启用默认构造函数" << endl;
	cin >> a;
	cin >> b;
}
MyClass::~MyClass()
{
	cout<<"该对象被析构"<<endl;
}
MyClass::MyClass(int x,int y)
{
	cout<<"启用自定义构造函数"<<endl;
	a = x;
	b = y;
}
MyClass::MyClass(const MyClass& m)
{
	cout << "启用自定义拷贝函数" << endl;
	MyClass *n=new MyClass;//这里开辟内存
	*n = m;
	cin>>a>>b;
}	
int main()
{
	int x = 100, y = 101;
	MyClass a;
	cout << a.a << " " << a.b <<" a的地址是"<<&a<< endl;
	MyClass *b = new MyClass;
	cout << b->a << " " << b->b << "b指向的地址是" << b<<" b的地址是 "<<&b<< endl;
	MyClass c(x,y);
	cout << c.a << " " << c.b <<" c的地址是" << &c << endl;
	MyClass *d=&a;
	cout << d->a << " " << d->b << " d指向的地址是 " << &d << " d本身的地址是 " << d << endl;
	MyClass e(a);//
	cout << e.a << " " << e.b << " e的地址是 " << &e << endl;
}

在这里插入图片描述

public
被public修饰的成员,实例化对象都能访问,我们一般将构造函数和析构函数设置为public,表示能实例化
protect
没什么好讲的,派生类能继承基类public和protect属性
private
被private修饰的成员实例化对象不能直接访问,只有类本身能访问和修改。实例化对象想要访问就要设置public类型的函数访问该private成员,实例化对象再访问public函数。被private修饰的构造函数和析构函数不能直接实例化,只有在类本身成员函数中实例化,在只有一个构造函数且被私有化的情况下,我们可以利用静态成员函数来实例化,这也是单例模式

class MyClass
{
public:
	static MyClass* create();//静态成员函数,整个内存独此一份
private:
	MyClass();
	~MyClass();
    int a, b;
};
MyClass::MyClass()	
{
	cout << "启用构造函数" << endl;
	cin >> a;
	cin >> b;
}
MyClass::~MyClass()
{
	cout<<"该对象被析构"<<endl;
}
MyClass* MyClass::create()
{
	MyClass *my=new MyClass;
	cout << my->a << " " << my->b << endl;
	cout << my << " " << &my << endl;
	return my;
}	
int main()
{
	MyClass *my1 = MyClass::create();
	cout <<  " " << my1 << " " << &my1 << endl;
	MyClass *my2= MyClass::create();
	cout << " " << my2 << " " << &my2 << endl;

在这里插入图片描述
再多的对象也是指向一个my
先来看看派生类的外部类的继承属性在这里插入图片描述

要注意的是派生类的实例化先是调用基类构造-派生类构造,释放的时候先析构派生类构造再析构基类构造,同时C++也支持多继承
内部类
内部类是类中嵌套的类,能访问外部类所以成员

static
c++静态有两个用法
(1)静态类成员变量。必须在类外初始化

elem class::name=;

静态成员变量在所有的实例化中共享一份内存,类似c语言函数的静态变量

 class MyClass
{
public:
	MyClass();
	~MyClass();
private:
	static int  x;
};
 MyClass::MyClass()
 {
	 x++;
	 cout << x << endl;
 }
MyClass::~MyClass()
{
}
int  MyClass::x=0;
int main()
{
	MyClass *a = new MyClass;
	MyClass *b = new MyClass;
	MyClass *c = new MyClass;
	MyClass *d = new MyClass;
	MyClass *e = new MyClass;
}

在这里插入图片描述
(2)修饰静态成员函数,注意3点:
2.1 只能访问静态成员
2.2 不能访问私有成员
2.3 非静态随便访问静态‘

 class MyClass
{
public:
	MyClass();
	~MyClass();
	char *a;
	static char *c;
	static void set();
private:
	char *b;
};
 MyClass::MyClass()
 {
 }
MyClass::~MyClass()
{
}
void MyClass::set()
{
	//a = new char;	//错误的方法 静态成员方法只能访问静态成员变量
	//b = new char;//错误的方法 静态成员方法不能访问私有变量
	c = new char;//
	cin >> c;
	cout << c ;
}
char *  MyClass::c =NULL;
int main()
{
	MyClass *a = new MyClass;
	MyClass::set();
	MyClass::set();
	MyClass::set();
}

在这里插入图片描述
this
其实就是实例化对象的指针,

 class MyClass
{
public:
	MyClass();
	~MyClass();
	MyClass* set(MyClass*);
 };
 MyClass::MyClass()
 {
 }
MyClass::~MyClass()
{
}
MyClass* MyClass::set(MyClass *m)
{
	cout << this << endl;
	cout << m<< endl;
	return this;
}
int main()
{
	MyClass *a = new MyClass;
	a->set(a);
}

在这里插入图片描述

friend
(1)友元类 ,有下面特点
1.1不能被继承
1.2不具有交换性和传递性
(2)友元函数
(3)友元成员函数 类A中的函数要成为类B的友元函数,则类A需要提前声明
菱形继承
出现于多继承中重复调用同一个函数的问题
解决办法
(1)域限定符·,多继承的子类A要调用一次多个父类(B,C,D…)中相同的函数(fun)则数用A.(B,C,D)::fun
(2)虚继承,在继承的时候加关键字virtual

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值