ahmadh
ahmadh

Reputation: 1652

Friend Function calling Static Members of Derived Classes. Not getting expected output

My first post here :)

I am having a problem with the following C++ code. I have an ABC class A, and two derived classes B and C. All of them have a static member called id:

using std::cout;

class A
{
private:
    friend int bar(A& a);
    static const int id = 1;

    virtual void foo() = 0;
};

class B : public A
{
private :
    friend int bar(A& a);
    static const int id = 2;

    void foo() { /*Do something*/ }
};

class C : public A
{
private:
    friend int bar(A& a);
    static const int id = 3;

    void foo() { /*Do something*/ }
};

int bar(A& a)
{
    return a.id;
}

int main()
{
    B b;
    C c;

    cout << bar(b) << "\n";
    cout << bar(c) << "\n";

    return 0;
}

I was expecting this code to print out 2 and 3 - rather it prints out 1 and 1 (bar() is always using A::id). What am I doing wrong? Any ideas?


Based on the comments below, this the final code I am using. It works, but would love to hear more thoughts :)

#include <iostream>

using std::cout;

class A
{
private:
    virtual void foo() = 0;
};

class B : public A
{
private:
    template <typename T>
    friend int bar(T& t);

    static const int id = 2;
    void foo() { /*do something*/ }
};

class C : public A
{
private:
    template <typename T>
    friend int bar(T& t);

    static const int id = 3;
    void foo() { /*do something*/ }
};


template <typename T>
int bar(T& t)
{
    return t.id;
}


int main()
{
    B b;
    C c;

    cout << bar(b) << "\n";
    cout << bar(c) << "\n";

    return 0;
}

Upvotes: 2

Views: 408

Answers (2)

Jesse Good
Jesse Good

Reputation: 52365

Is there any way to avoid writing int foo() { return id; } for all the derived classes?

Yes, using templates. For example:

template <typename T>
int foo (T& x)
{
    return x.id;
}

However, if id is private, this doesn't reduce the code by all that much.

Upvotes: 1

Dmitry Shkuropatsky
Dmitry Shkuropatsky

Reputation: 3965

a.id will be defined at compile-time as A::id. You would need to define a virtual member (non-static) function in class A and have it overridden in B and C to return their respective ids and call this function in bar.

Upvotes: 2

Related Questions