关于类成员函数中访问同类对象的私有成员

本文详细阐述了C++中类成员函数如何访问同一类对象的私有成员,并通过具体例子说明了拷贝构造函数、成员函数等不同场景下的访问方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原址:http://wenku.baidu.com/view/4e13d5343968011ca300912c.html


(注释: 为了尊重原作者,在不改变内容的前提下,我进行了格式和内容的编辑,增强阅读体验。这位兄弟的文章,挺全面的,不过也有一点啰嗦。好像这个文章的上传作者也在杭州工作,有机会联系下,一起讨论交流下C++的一些知识。)

关于类成员函数中访问同类对象的私有成员,主要包含以下几种场景:
a. 在C++的类的成员函数中,允许直接访问该类的对象的私有成员变量。
b. 在类的成员函数中可以访问同类型实例的私有变量。
c. 拷贝构造函数里,可以直接访问另外一个同类对象(引用)的私有成员。
d. 类的成员函数可以直接访问作为其参数的同类型对象的私有成员。

举例描述上述知识:
1).在拷贝构造函数中可以访问引用对象的私有变量:例如:

class Point {
public:
Point(int xx=0,int yy=0)
{
X=xx;
Y=yy;
}

Point(Point &p);

private:
int X,Y;
};


Point::Point (Point &p)
{
X=p.X;
Y=p.Y;
}


2). 在类的成员函数中可以访问同类型实例的私有变量

class A {
public:
int getA() const
{
return a;
}
void setA(int val)
{
a = val;
}
void assign(A& _AA)
{
this->a = _AA.a;
_AA.a = 10; //可以直接访问
}

void display()
{
cout<<"a:"<<a<<endl;
}
private:
int a;
};



3).

#include <iostream>
using namespace std;
class TestClass {
public:
TestClass(int amount)
{
this->_amount = amount;
}
void UsePrivateMember()
{
cout<<"amount:"<<this->_amount<<endl;

TestClass objTc(10);
objTc._amount = 15;
//访问同类型实例的私有变量
cout<<objTc._amount<<endl;
}
private:
int _amount;
};


4).

#include <iostream>
using namespace std;
class TestClass {
public:
TestClass(int amount)
{
this->_amount = amount;
}
void UsePrivateMember()
{
cout<<"amount:"<<this->_amount<<endl;

TestClass objTc(10);
objTc._amount = 15;
//访问同类型实例的私有变量
cout<<objTc._amount<<endl;
}
private:
int _amount;
};


int main() {
TestClass tc(5);
tc.UsePrivateMember();
return(0);
}



关于该问题(知识点)的讨论和或解释:
1.
私有是为了实现“对外”的信息隐藏,或者说保护,在类自己内部,有必要禁止私有变量的直接访问吗?

难道还要让我们声明一个类为自身的友元?
Point::Point(Point &p)
{
X=p.X;
Y=p.Y;
}

请记住你是在定义你的类,不是在用。


2. C++的访问修饰符的作用是以类为单位,而不是以对象为单位。

通俗的讲,同类的对象间可以“互相访问”对方的数据成员,只不过访问途径不是直接访问.

步骤是:
通过一个对象调用其public成员函数,此成员函数可以访问到自己的或者同类其他对象的public/private/protected数据成员和成员函数(类的所有对象共用),而且还需要指明是哪个对象的数据成员(调用函数的对象自己的成员不用指明,因为有this指针;其他对象的数据成员可以通过引用或指针间接指明)

可以提供访问行为的主语为“函数”。

类体内的访问没有访问限制一说,即private函数可以访问public/protected/private成员函数或数据成员,同理,protected函数,public函数也可以任意访问该类体中定义的成员public继承下,基类中的public和protected成员继承为该子类的public和protected成员(成员函数或数据成员),然后访问仍然按类内的无限制访问。

3. 注意公有和私有的概念:

每个类的对象都有自己的存贮空间,用于存储内部变量和类成员;但同一个类的所有对象共享一组类方法,即每种方法只有一个源本。

很明显,类方法是所有该类对象共同使用的,因此不存在每个对象有一组类方法的副本。源本的类方法自然可以访问所有该类对象的私有成员。

4. 访问权限是相对于类而言,而非对象!

一个问题,为什么成员函数可以访问私有成员呢?

结果很显然,如果不能访问,那么私有成员的存在就没有了意义。

而对于成员函数中允许访问对象的数据成员,一方面保证了安全性与封装性,另一方面提供方便的操作。

第一句话的解释,就是承认只有成员函数可以访问私有成员,这里不涉及友元及派生。这样一来,安全性仍然得到了保证,也完成了封装工作。

对于第二句话,试想,如果都得靠接口来实现数据传送,那么操作是否极为不便?既然处于成员函数中,已经保证了足够的安全和封装性,那么这里如果还得借助接口,就有些不合情合理了。

作为对数据成员的灵活处理,设计者允许在成员函数中访问对象的私有成员,为使用者提供了很大的方便。这同时也反映了语言的灵活性和原则性.



C++中类访问权限控制:
第一:private, public, protected 访问标号的访问范围,在没有继承的情况下:
private:
只能由1.该类中的函数、2.其友元函数访问。 不能被任何其他访问,该类的对象也不能访问。

protected:
可以被1.该类中的函数、2.子类的函数、以及3.其友元函数访问。 但不能被该类的对象访问。

public:
可以被1.该类中的函数、2.子类的函数、3.其友元函数访问,也可以由4.该类的对象访问。
注:友元函数包括3种:设为友元的普通的非成员函数;设为友元的其他类的成员函数;设为友元类中的所有成员函数。

第二:类的继承后方法属性变化,具体情况如下:

private 属性是不能够被继承的,protected继承和private继承能降低访问权限。

使用private继承,父类的protected和public属性在子类中变为private;

使用protected继承,父类的protected和public属性在子类中变为protected;

使用public继承,父类中的protected和public属性不发生改变;

如下所示:

class A {
public:
A(int i) : a(i){}

protected:
int a;
};

class B : public A {
public:
B(int i) : A(i) {}
void fb(A &a)
{
cout<<a.a<<endl;
}
};


编译出错;
若将fb成员函数改为 :

void fb(B &a)
{
cout<<a.a<<endl;
}

则编译运行都没问题:

保护类型只能被本类中的方法或者派生类访问,不能被本类的具体对象访问。
a是类A的保护类型成员,能被A中的方法(函数)访问,能被B类访问, 不能被类A的具体对象访问

一个类的保护成员或私有成员只能被该类的成员函数或该类的友元函数来访问,外部代码不能访问。
B类中的函数fb,对于A类中的保护成员变量a,是外部代码不能通过该类的对象直接访问。
由于B类公有继承了A类,a在A类中是保护成员,则在B类中也是保护成员,因此B类中的函数可以访问自己的保护成员。




<think>嗯,用户问的是C++私有成员能否被派生类的成员函数访问,这涉及到面向对象中封装和继承的核心概念。从用户引用资料看,他应该已经查阅过友元、公有接口访问等其他跨类访问方式,现在聚焦在派生类权限问题上。用户的问题很清晰,但引用资料[3]提到的“类成员函数访问同类不同对象私有成员”可能让用户产生混淆——这其实讨论的是同类对象间的访问权限,而非继承关系中的权限。需要明确区分这两种场景。先回顾C++基础规则:基类的private成员在任何派生类中都不可见。用户可能期待protected权限的效果,因为protected正是为派生类访问而设计的。不过引用资料里没提到protected,说明用户可能对这个中间权限层级不熟悉。需要强调两个关键点:首先是封装原则(私有成员严禁外部访问),其次是继承时的权限变化(不同继承方式会影响基类成员的派生类可见性)。用户误用private时常见的编译错误,比如派生类试图调用基类私有方法,这个具体例子比理论更能说明问题。考虑到用户提到Qt开发经历,补充实际工程中的惯用做法会更有帮助。比如Qt的Pimpl模式(d-pointer)通过公有接口访问私有数据,这种模式能保持封装性又解决跨类访问问题,比友元更安全可控。最后要提醒用户注意基类成员访问声明位置:private阻止一切外部访问,protected允许派生类访问,而派生类自身成员的访问权限设置同样重要。用表格对比三种成员权限的可见范围会比较直观,但当前文本环境无法使用表格,改用三组对比示例代码应该足够清晰。</think> 在C++中,**基类的私有成员不能被派生类的成员函数直接访问**。这是面向对象编程封装性的核心原则,具体分析如下: --- ### 📌 核心规则 1. **`private`成员** - 仅允许**声明该成员的类自身**访问 - 派生类(包括其成员函数)**不可直接访问**基类的私有成员 $$代码验证:$$ ```cpp class Base { private: int privateVar; // 基类私有成员 }; class Derived : public Base { public: void tryAccess() { // privateVar = 10; // 编译错误:'int Base::privateVar' is private } }; ``` 2. **`protected`成员**(特殊场景) - 若需要派生类访问类成员,需将成员声明为 `protected` ```cpp class Base { protected: // ✅ 允许派生类访问 int protectedVar; }; class Derived : public Base { public: void accessBase() { protectedVar = 20; // 合法访问 } }; ``` --- ### ⚙️ 派生类访问私有成员的间接方法 1. **基类提供公有接口**(推荐) ```cpp class Base { private: int privateVar; public: int getVar() const { return privateVar; } // 通过公有函数暴露 void setVar(int v) { privateVar = v; } }; class Derived : public Base { public: void modifyVar() { setVar(getVar() + 1); // 通过基类公有函数间接操作 } }; ``` 2. **使用友元关系**(破坏封装性,慎用) ```cpp class Derived; // 前向声明 class Base { private: int privateVar; friend class Derived; // 授予派生类友元权限 ✅ }; class Derived : public Base { public: void accessBase() { privateVar = 30; // 友元允许直接访问 } }; ``` --- ### 🌰 关键对比表 | 成员类型 | 同类访问 | 派生类访问 | 类外访问 | |------------|----------|------------|----------| | `private` | ✅ | ❌ | ❌ | | `protected`| ✅ | ✅ | ❌ | | `public` | ✅ | ✅ | ✅ | --- ### 💎 结论 基类的私有成员对派生类**严格不可见**,这是C++封装性的设计原则。若需派生类访问类成员: 1. **优先用`protected`修饰成员** 2. **通过基类公有接口间接访问** 3. 避免滥用`友元`(会破坏封装性)[^2][^3] --- ### ✨ 相关问题 1. `protected`和`private`在多重继承中有何区别? 2. 派生类能否访问基类私有成员的地址? 3. 友元关系在类继承体系中如何传递? 4. C++11的`final`关键字如何影响成员访问权限?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值