简体   繁体   中英

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;

};


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是你的friend通过提及你想要在你想要使用的班级中作为朋友访问的班级来使用该关键词!

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.

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....

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM