Friend函数调用派生类的静态成员。没有得到预期的产出

时间:2012-01-19 23:38:17

标签: c++ static friend

我的第一篇帖子:)

我遇到以下C ++代码的问题。我有一个ABC类A和两个派生类B和C.它们都有一个名为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;
}

我期待这段代码打印出2和3 - 而是打印出1和1(bar()总是使用A :: id)。我究竟做错了什么?有什么想法吗?


根据以下评论,这是我正在使用的最终代码。它有效,但很想听到更多的想法:)

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

2 个答案:

答案 0 :(得分:2)

a.id将在编译时定义为A::id。您需要在类A中定义一个虚拟成员(非静态)函数,并在BC中重写它以返回其各自的id并调用此函数bar中的函数。

答案 1 :(得分:1)

  

有没有办法避免为所有派生类编写int foo() { return id; }

是的,使用模板。例如:

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

但是,如果id是私有的,那么这并不会减少代码。