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

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

cpp 复制代码
#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)通过公有函数为私有成员赋值

cpp 复制代码
#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)利用指针访问私有数据成员

cpp 复制代码
#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 方法来实现,这样可以保护私有成员不被外部直接访问和修改。例如:

cpp 复制代码
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)。这是面向对象编程的一种常见做法,它有助于保护数据的完整性和封装性。

cpp 复制代码
#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**在构造函数中直接访问私有成员:

cpp 复制代码
#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++中,通过引用访问私有数据成员是一种较为间接的方法。由于私有成员被封装在类中,理论上只能通过类的方法进行访问。但是,我们可以通过在类外部定义一个指向私有成员的公有引用,来间接访问这些私有成员。

下面是一个简单的例子:

cpp 复制代码
#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 小时前
C++ 面向对象
c++
CoovallyAIHub12 小时前
中科大DSAI Lab团队多篇论文入选ICCV 2025,推动三维视觉与泛化感知技术突破
深度学习·算法·计算机视觉
沐怡旸12 小时前
【底层机制】std::shared_ptr解决的痛点?是什么?如何实现?如何正确用?
c++·面试
NAGNIP13 小时前
Serverless 架构下的大模型框架落地实践
算法·架构
moonlifesudo13 小时前
半开区间和开区间的两个二分模版
算法
moonlifesudo13 小时前
300:最长递增子序列
算法
CoovallyAIHub18 小时前
港大&字节重磅发布DanceGRPO:突破视觉生成RLHF瓶颈,多项任务性能提升超180%!
深度学习·算法·计算机视觉
感哥18 小时前
C++ STL 常用算法
c++
CoovallyAIHub18 小时前
英伟达ViPE重磅发布!解决3D感知难题,SLAM+深度学习完美融合(附带数据集下载地址)
深度学习·算法·计算机视觉
saltymilk1 天前
C++ 模板参数推导问题小记(模板类的模板构造函数)
c++·模板元编程