This would be trivial but it comes with a serious catch - I can't edit the Unrelated or Friend class. I can't seem to access a private data member despite the friend relationship between the classes. Code:
http://pastie.org/613042

class UnrelatedClass
{
  ...
private:
  friend class FriendClass;
  float m_fNumber;
}

class FriendClass
{
public:
  CHandle<UnrelatedClass>  m_hUnrelatedClass;
  void Bar();
}

class DerivedClass : public FriendClass
{
public:
  ...
  void Foo();
  ...
}

void FriendClass::Bar()
{
  m_hUnrelatedClass->m_fNumber = 2.0; // no error
}

void DerivedClass::Foo()
{
  ...
  FriendClass *friendClass = static_cast<FriendClass *>( this );
  friendClass->m_hUnrelatedClass->m_fNumber = 2.0; // produces error
  ...
}

// error C2248: 'UnrelatedClass::m_fNumber' : cannot access private member declared in class 'UnrelatedClass'

I don't understand how the compiler can tell the difference between being in the class and just have it accessed from an object. Is there anyway around this WITHOUT altering the FriendClass or UnrelatedClass? I very much appreciate your thoughts on this.

Recommended Answers

All 3 Replies

Classes don't inherit friends and subclasses can't access base class's private members

commented: I agree! +14

Classes don't inherit friends and subclasses can't access base class's private members

I understand both of those facts but I thought that here, I'm only accessing the private members via the friend class, which I thought would be okay.

Is there any ugly hack I can use to get around this?

I understand both of those facts but I thought that here, I'm only accessing the private members via the friend class, which I thought would be okay.

Making a friend to a class does not make the private members public. FriendClass can access UnrelatedClass' private members, but those private members are still private. Users of FriendClass cannot access them any more than non-friends of UnrelatedClass can.

Is there any ugly hack I can use to get around this?

There are a few, and none of them are recommended. But since you asked for an ugly hack, I will show you one. Use it at your own risk:

void DerivedClass::Foo()
{
    *reinterpret_cast<float*>(m_hUnrelatedClass) = 2.0;
}

This hack assumes that CHandle<> is a smart pointer. Do whatever you need to do to get the address of the UnrelatedClass object pointed to by the field.

It works like this: UnrelatedClass has no virtual members, which means the object structure is easier to predict with some accuracy. There is only one field and it is the field you want, so you can assume that for an object of UnrelatedClass, &obj.fNumber is the same address as &obj. If that is true and you cast that address to float*, you can access fNumber even though it is private.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.