开发者

C++ protected access

is there anyway i can access a protected variable in a class without inheritance.

class ClassA{
  protected:
    int varA; 
};

class ClassB{
  protected:
    ClassA objectA开发者_如何学Go;

};


ClassB theMainObject;

I would like to access varA through theMainObject.


You could make classB friend of classA

class ClassA{
  protected:
    int varA; 

  friend ClassB;
}

but using a accessors would probably be better since you are not coupling the classes together.

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


Have an accessor function is the only way ie;

public:
   int getVarA(){return varA;}


Add standard getter/setter functions:

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;
}


friend is your friend.Use that keyword by mentioning the class in which you want to access as a friend in the class for which u want to use!


You can't, and quite possibly shouldn't, access varA directly from theMainObject. protected is the same as private for unrelated classes (such as your two example class) so varA has no visibility. Use ClassA's normal API to manipulate its state.

If varA is part of the result state of ClassA and you just need read access to it, then you should add a public accessor to that class:

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


Besides of making ClassB a friend of ClassA there are some standard and non-standard hacks to get to ClassA internals. You can read Herb Sutter's article about them.


I assume modifying definition of ClassA is forbidden.

Here is a tricky way for you, but I don’t encouraging you to use it :)

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;
}

So there is a way to access and modify protected/private data.
Who was thinking it is impossible, vote up ;)


As Mark B mentionned, solution proposed by Hovhannes Grigoryan is not safe and may have unexpected behaviour because ProtectedRemover and classA are unrelated....

I used this in the past, and it may be safer I think:

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);
   }
};

Note it presents no risk at all to get undetermined behaviour....but may be less than original solution where ProtectedRemover and classA were unrelated....and also easier to do if ClassA has tones of attributes!

Still not recommended unless you really have no other choice (can't modify classA by making your class friend or add settre/getter)!

Nothing's really impossible....

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜