C++【5】类与对象(二)

1.类的嵌套:在定义一个类时,在其类体中又包含了一个类的完整定义,称为类的嵌套。类时允许嵌套定义的。

#include<iostream>
using namespace std;

class demo1
{
	public :
	  int x;
	  void Func();
	
	class demo2
	{
		int x;
		void Func();
	}obj;
	
};

void demo1::Func()
{
	x = 3000;
	cout << "x=" << x << endl;	
}

void demo1::demo2::Func()
{
		x = 40000;	
		cout << "x=" << x << endl;	
}

int main()
{
	class demo1 obj;
	obj.Func();
	obj.obc.Func();
	
	cout <<"\n\n";
	cout <<"2:x= " << obj.x << endl;
	cout <<"2:x= " << obj.objc.x <<endl;
	return 0;
}

 2.对象引用私有数据成员

(1)通过公有函数为私有成员赋值

#include<iostream>
#include<string>

using namespace std;

class 	Person   //定义一个 个人类
{
	private :  //定义私有属性
		string name;
		int	age;
	public:		//公有属性
		void setInfo(string n ,int a)  //设置信息
		{
			name = n;	//通过公有函数为私有成员赋值
			age  = a;
		}
		void displayInfo()				//显示信息
		{
			cout << "Name" << name <<endl;
			cout <<	"Age"  << age  <<endl;
		}
};

int main()
{
	//函数引用
	Person p;
	p.setInfo("Tammy",24);
	p.dispalyInfo();
	return 0;	
}

(2)利用指针访问私有数据成员

#include<iostream>

class MyClass{
private:
	int myPrivateData;  //定义一个私有数据

public:
	MyClass():myPrivateData(10){}
   
	void showPrivateData(){
		std::cout<<"private data" << myPrivateData << std::endl;	
	}
};

int  main()
{
	MyClass obj;  //1.首先创建了一个MyClass的对象obj
	int *ptr  = reinterpret_cast<int*>(&obj); //2.然后创建 指针指向Myclass的第一个字节
	std::cout<<"private data before:"<< obj.myPrivatedata << std::endl; //3.
	*ptr = 20;  //由于MyClass的大小必须大于一个int的大小,所以我们可以通过指针ptr来访问或修改myPrivateData的值。
	std::cout<<"private data after"<< obj.myprivatedata <<std ::endl;
	obj.showPrivate();
	
	return 0;	
}

        在这个例子中,我们首先创建了一个MyClass的对象obj,然后我们创建了一个指向MyClass的第一个字节的指针ptr。由于MyClass的大小必须大于一个int的大小,所以我们可以通过指针ptr来访问或修改myPrivateData的值。请注意这种方法是很危险的,因为它依赖于特定的内存布局,不应在实际开发中使用。

        一般来说,如果你需要访问类的私有成员,应该通过 getter 和 setter 方法来实现,这样可以保护私有成员不被外部直接访问和修改。例如:

class MyClass {  
private:  
    int myPrivateData;  
  
public:  
    MyClass(): myPrivateData(10) {}  
  
    int getMyPrivateData() {  
        return myPrivateData;  
    }  
  
    void setMyPrivateData(int data) {  
        myPrivateData = data;  
    }  
};

        在这个例子中,你可以通过调用getMyPrivateData()setMyPrivateData()方法来访问和修改私有成员myPrivateData

(3)利用函数访问私有数据成员

        在C++中,如果你想让其他函数访问类的私有数据成员,通常的做法是通过提供公有的成员函数(getter和setter)。这是面向对象编程的一种常见做法,它有助于保护数据的完整性和封装性。

#include <iostream>  
  
class MyClass {  
private:  
    int myPrivateData; // 私有数据成员  
  
public:  
    MyClass() : myPrivateData(10) {} // 构造函数,初始化私有数据成员  
  
    // 公有成员函数,获取私有数据成员的值  
    int getMyPrivateData() {  
        return myPrivateData;  
    }  
  
    // 公有成员函数,设置私有数据成员的值  
    void setMyPrivateData(int data) {  
        myPrivateData = data;  
    }  
};  
  
int main() {  
    MyClass obj;  //创建一个MyClass的对象obj
    std::cout << "Private Data: " << obj.getMyPrivateData() << std::endl; // 调用getter函数获取私有数据成员的值  
    obj.setMyPrivateData(20); // 调用setter函数设置新的值  
    std::cout << "Private Data: " << obj.getMyPrivateData() << std::endl; // 再次调用getter函数获取修改后的值  
  
    return 0;  
}

        然而,如果你真的需要其他的函数直接访问私有数据成员(这并不推荐,除非有特殊的理由),你可以在类内部提供公有的成员函数来访问。但是要注意,这种做法破坏了封装性,可能导致数据被随意修改,或者引入其他的问题。

        在C++11及以后的版本中,还可以使用std::initializer_list在构造函数中直接访问私有成员:

        

#include <iostream>  
#include <initializer_list>  
  
class MyClass {  
private:  
    int myPrivateData;  
  
public:  
    MyClass(std::initializer_list<int> list) : myPrivateData(list.begin()[0]) {}  
};  
  
int main() {  
    MyClass obj({10}); // 通过初始化列表在构造函数中访问私有成员  
    std::cout << "Private Data: " << obj.myPrivateData << std::endl;  
    return 0;  
}

        在这个例子中,通过使用初始化列表来创建MyClass的实例,我们可以直接访问和设置myPrivateData的值。但是这种做法也有其局限性,它只适用于在构造函数中设置私有成员的值,并且只能通过初始化列表来创建对象。

(4)利用引用访问私有数据成员

        在C++中,通过引用访问私有数据成员是一种较为间接的方法。由于私有成员被封装在类中,理论上只能通过类的方法进行访问。但是,我们可以通过在类外部定义一个指向私有成员的公有引用,来间接访问这些私有成员。

下面是一个简单的例子:

#include <iostream> 

class MyClass { 
private: 
    int myPrivateData; // 私有数据成员 

public: 
    MyClass() : myPrivateData(10) {} 

    // 公有引用,访问私有数据成员 
    int& myPrivateDataRef = myPrivateData; 
}; 

int main() { 
    MyClass obj; 
    std::cout << "Private Data: " << obj.myPrivateDataRef << std::endl; // 访问私有数据成员 
    obj.myPrivateDataRef = 20; // 修改私有数据成员的值 
    std::cout << "Private Data: " << obj.myPrivateDataRef << std::endl; // 再次访问私有数据成员 

return 0; 
}

        在这个例子中,我们定义了一个MyClass类,并在类内部初始化了一个私有数据成员myPrivateData。然后,我们定义了一个公有的引用myPrivateDataRef,指向这个私有数据成员。这样,我们就可以通过myPrivateDataRef间接访问和修改myPrivateData的值。

        需要注意的是,虽然这种方法可以间接访问私有数据成员,但是它并没有破坏类的封装性。因为myPrivateDataRef只是一个引用,它并不能独立存在,必须依附于类的对象。同时,我们仍然可以通过在类中定义其他方法来控制对myPrivateData的访问。因此,这种方法并不会破坏面向对象编程中的封装原则。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值