naive231
naive231

Reputation: 1380

How to compare 2 objects' private member?

I have 2 class:

class A
{
    int aa;
};
class B
{
    int bb;
};
class C
{
    public:
        bool equal(A& av,B& bv)
        {
            return (av.aa==bv.bb);
        }
};

Of course, class C has compilation error cause of private members' access. Is there a way to implement that equal() member of class C ?

Upvotes: 2

Views: 3052

Answers (9)

Bert te Velde
Bert te Velde

Reputation: 853

Without commenting on the relevance of the request, or alternatives for the presumed underlying reason, I believe you can compare private members thru Reflection:

FieldInfo AInfo = av.GetType().GetField("aa", BindingFlags.NonPublic | BindingFlags.Instance);
int AValue = (int) AInfo.GetValue(av);

etcetera

Upvotes: -2

Open AI - Opting Out
Open AI - Opting Out

Reputation: 24133

Why do you need this?

Combine behaviour with the data.

class C
{
public:
    void doSomething()
    {
        if(aa == bb) {
            doThis();
        } else
            doThat();
        }
    }
private:
    int aa;
    int bb;
};

Upvotes: -1

Tom Tanner
Tom Tanner

Reputation: 9354

I see questions like this and I ask why. There'a apparently no relationship between class A and class B beyond that they have an int.

The way to make this compile is to make C a friend of A and B, or at least make the equal function in C a friend of A and B (with careful use of forward declarations).

class A;
class B;
class C { static bool equal(A const &, B const &); };
class A { friend bool C::equal(A const &, B const &) };
class B { friend bool C::equal(A const &, B const &) };
bool C::equal(A& const &a, B const &b) { return a.a == b.b; }

Please note the const qualifier as it is unlikely that a comparison operator is meant to alter its input. Moreoever I have made it a static function as it doesn't use any of the members of C - it is completely unrelated. (as per your snippet).

Basically - that's how you do it. But don't do it without a LOT of thought. Just because apples and oranges both have pips, doesn't mean there's a lot of point in comparing the numbers of pips.

Upvotes: 4

Richard J. Ross III
Richard J. Ross III

Reputation: 55563

This is a great scenario for using friend functions:

// forwarding references to each of the classes
class A;
class B;
class C
{
public:
    bool equal(A& av,B& bv);
    // notice we cannot implement equal() here, 
    // because A and B have not been defined yet, 
    // even though they have been declared.
};

class A
{
private:
    int aa;

    // Simply register to be a friend of A with our 'C::equal' function,
    // so that we can access 'aa' 
    friend bool C::equal(A&, B&);
};
class B
{
private:
    int bb;

    // Once again, we register as a friend of C::equal,
    // this time to access 'bb'
    friend bool C::equal(A&, B&);
};

// finally, now that A and B have been fully defined,
// we can implement our equal method:
bool C::equal(A&av, B&bv)
{
    return (av.aa == bv.bb);
}

// Sample Usage
int main()
{
    A a = A();
    B b = B();

    C c = C();

    c.equal(a, b);
}

Upvotes: 6

Saage
Saage

Reputation: 363

You could make A and B to be friend of C or add int GetVar() const methods to A and B classes.

Upvotes: 0

Lews Therin
Lews Therin

Reputation: 10995

A good solution might be to provide getters in A and B classes. This way you keep everything encapsulated. e.g.

class A
{
    int aa;
    public:
     int GetAA()
     {
       return aa ;
     }

};

Upvotes: 10

UmNyobe
UmNyobe

Reputation: 22890

If they are private and cannot be accessed via any kind of public interface it means conceptually they have nothing in common. so add public getAA getBB and use it to make the comparator between objects. I dislike friendship. A lot.

Upvotes: 0

rplusg
rplusg

Reputation: 3446

Form friendship with two classes(c & a , c & b) and then compare.

Upvotes: 0

unwind
unwind

Reputation: 399813

You can make the classes friends with each other.

But, as pointed out in comments, that's pretty horrible in most cases. The reason the member is private has to be because outside parties shouldn't access it directly.

So, either add operator==() overloads to A and B that can be used (i.e. an bool A::equal(const B&) const; method), or add accessors to return the value for external comparison.

Upvotes: 2

Related Questions