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的访问。因此,这种方法并不会破坏面向对象编程中的封装原则。

相关推荐
SpongeG26 分钟前
数据结构第三周做题总结_链表
数据结构·算法·链表
everyStudy27 分钟前
前端五种排序
前端·算法·排序算法
小珑也要变强27 分钟前
队列基础概念
c语言·开发语言·数据结构·物联网
醉竺31 分钟前
【高阶数据结构】二叉搜索树的插入、删除和查找(精美图解+完整代码)
数据结构
未来可期LJ2 小时前
【C++ 设计模式】单例模式的两种懒汉式和饿汉式
c++·单例模式·设计模式
Trouvaille ~2 小时前
【C++篇】C++类与对象深度解析(六):全面剖析拷贝省略、RVO、NRVO优化策略
c++·c++20·编译原理·编译器·类和对象·rvo·nrvo
little redcap2 小时前
第十九次CCF计算机软件能力认证-乔乔和牛牛逛超市
数据结构·c++·算法
AI原吾3 小时前
掌握Python-uinput:打造你的输入设备控制大师
开发语言·python·apython-uinput
机器视觉知识推荐、就业指导3 小时前
Qt/C++事件过滤器与控件响应重写的使用、场景的不同
开发语言·数据库·c++·qt
毕设木哥3 小时前
25届计算机专业毕设选题推荐-基于python的二手电子设备交易平台【源码+文档+讲解】
开发语言·python·计算机·django·毕业设计·课程设计·毕设