C++ C++;受保护访问

C++ C++;受保护访问,c++,C++,我是否可以访问类中的受保护变量而无需继承 class ClassA{ protected: int varA; }; class ClassB{ protected: ClassA objectA; }; ClassB theMainObject; 我想通过主对象访问varA。拥有访问器功能是ie的唯一方式 public: int getVarA(){return varA;} 你可以成为classB的朋友classA class ClassA{

我是否可以访问类中的受保护变量而无需继承

class ClassA{
  protected:
    int varA; 
};

class ClassB{
  protected:
    ClassA objectA;

};


ClassB theMainObject;

我想通过主对象访问varA。

拥有访问器功能是ie的唯一方式

public:
   int getVarA(){return varA;}

你可以成为
classB
的朋友
classA

class ClassA{
  protected:
    int varA; 

  friend ClassB;
}
但是使用访问器可能会更好,因为您没有将类耦合在一起

class ClassA{
  int getA() { return varA;}
  void setA(int a) { varA = a; }
  protected:
    int varA; 
}

friend
是您的朋友。请使用该关键字,并在您要使用的类中以朋友身份提及您要访问的类

我假设禁止修改ClassA的定义

这里有一个棘手的方法,但我不鼓励您使用它:)

A类
{
受保护的:
内瓦拉;
};
类ProtectedRemover//神奇的东西
{
public://varA;
}
无效setProtectedVarA(int i)
{
重新解释强制转换(&objectA)->varA=i;
}
};
int main()
{
B类主要对象;
//设置受保护的对象。
主对象setProtectedVarA(3);
//得到保护。

std::cout您不能,也很可能不应该,直接从
主对象
访问
varA
受保护的
与不相关类(例如您的两个示例类)的private相同,因此
varA
没有可见性。使用
ClassA
的正常API来操作其状态

如果
varA
ClassA
的结果状态的一部分,并且您只需要对其进行读取访问,那么您应该向该类添加公共访问器:

public:
   int getVarA() const
   {
       return varA;
   }

除了让ClassB成为ClassA的朋友之外,还有一些标准和非标准的黑客可以访问ClassA内部。您可以阅读它们。

添加标准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;
}

正如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);
   }
};
A类
{
受保护的:
内瓦拉;
};
class ProtectedRemover:public ClassA//现在,它们是相关的!
{
public://getA();
}
无效setProtectedVarA(int i)
{
((ProtectedRemover)*(&objectA))->setA(i);
}
};
注意:它不会带来任何不确定行为的风险……但可能比原始解决方案(ProtectedRemover和classA不相关)要小……而且如果classA有属性的音调,也更容易做到

仍然不推荐,除非你真的没有其他选择(不能通过交你的类朋友或添加settre/getter来修改classA)


没有什么是真的不可能的….

你应该让它成为
int getCarA()const
。你是对的@Space\u C0wb0y,我通常懒得标记const函数:p-1这是未定义的行为,因为这些类型在编译器看来是不相关的,特别是如果
ClassA
有虚拟方法,OP没有告诉我们。问题中没有虚拟函数!为什么这里的人都愿意投反对票?我知道您也发布了一个答案,但仍然不公平:)为什么您认为作者不知道如何向ClassA添加访问者?:)你的答案应该先被否决:)如果不是因为你的愚蠢,我会把你的创造性答案投上赞成票(事实上是这样的),只是因为对Mark-B答案的评论。太糟糕了,朋友,这不是处理批评的方法。你唯一可以做的事情就是把《重新解释》的结果重新转换成原来的类型。所有其他用途调用UB。无论如何,在许多编译器中,这可能是可行的。@Hovhannes这是未定义的行为。只是因为它碰巧可以工作并不意味着它就不那么正确,它可能在某些编译器上甚至在同一编译器的未来版本上都不起作用。-1因为我的创造性答案被否决,因为你认为作者不知道如何添加访问器!!!:)我同意。但我不会投反对票,因为我非常感谢你的帮助。
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);
   }
};