无论如何我可以在没有继承的情况下访问类中的受保护变量。
class ClassA{
protected:
int varA;
};
class ClassB{
protected:
ClassA objectA;
};
ClassB theMainObject;
我想通过theMainObject访问varA。
答案 0 :(得分:5)
您可以classB
classA
朋友
class ClassA{
protected:
int varA;
friend ClassB;
}
但是使用访问器可能会更好,因为你没有将这些类耦合在一起。
class ClassA{
int getA() { return varA;}
void setA(int a) { varA = a; }
protected:
int varA;
}
答案 1 :(得分:3)
有一个访问者功能是唯一的方式,即;
public:
int getVarA(){return varA;}
答案 2 :(得分:2)
添加标准的getter / setter函数:
int ClassA::GetVarA()
{
return varA;
}
BOOL ClassA::SetVarA(int nNewVar)
{
// Perform verifications on nNewVar... Return FALSE if didn't go well.
// We're satisfied. Set varA to the new value.
varA = nNewVar;
return TRUE;
}
答案 3 :(得分:1)
friend
是你的朋友。通过提及你想要在你想要使用的班级中作为朋友访问的班级来使用该关键字!
答案 4 :(得分:1)
您不能,也很可能不会直接从varA
访问theMainObject
。对于不相关的类(例如您的两个示例类),protected
与私有相同,因此varA
没有可见性。使用ClassA
的普通API来操纵其状态。
如果varA
是ClassA
的结果状态的一部分,并且您只需要对它的读取权限,那么您应该为该类添加一个公共访问者:
public:
int getVarA() const
{
return varA;
}
答案 5 :(得分:1)
除了让B级成为Class的朋友之外,还有一些标准和非标准的黑客可以进入ClassA内部。您可以阅读有关它们的Herb Sutter's article。
答案 6 :(得分:0)
我认为禁止修改ClassA的定义。
这对你来说很棘手,但我不鼓励你使用它:)
class ClassA
{
protected:
int varA;
};
class ProtectedRemover // magic thing
{
public: // <- Note this! :)
int varA;
};
class ClassB
{
protected:
ClassA objectA;
public: // Just add two methods below
int getProtectedVarA()
{
return reinterpret_cast<ProtectedRemover*>(&objectA)->varA;
}
void setProtectedVarA(int i)
{
reinterpret_cast<ProtectedRemover*>(&objectA)->varA = i;
}
};
int main()
{
ClassB theMainObject;
// Set protected thing.
theMainObject.setProtectedVarA(3);
// Get protected thing.
std::cout << theMainObject.getProtectedVarA() << std::endl;
}
因此,有一种方法可以访问和修改受保护/私有数据 谁认为这是不可能的,投票;)
答案 7 :(得分:0)
正如Mark B所提到的,Hovhannes Grigoryan提出的解决方案并不安全,可能会出现意外行为,因为ProtectedRemover和classA是无关的......
我过去使用过这个,我认为它可能更安全:
class ClassA
{
protected:
int varA;
};
class ProtectedRemover : public ClassA // now, they are related!
{
public: // <- Note this! :)
int getA() { return varA; }
void setA( int a ) { varA = a; }
};
class ClassB
{
protected:
ClassA objectA;
public: // Just add two methods below
int getProtectedVarA()
{
return ((ProtectedRemover)*(&objectA))->getA();
}
void setProtectedVarA(int i)
{
((ProtectedRemover)*(&objectA))->setA(i);
}
};
注意,它没有任何风险可以获得未确定的行为....但可能比ProtectedRemover和classA不相关的原始解决方案要少......如果ClassA具有属性的音调,也更容易做到!
仍然不推荐,除非你真的别无选择(不能通过让你的班级朋友修改classA或添加设置/获取者)!
没有什么不可能......