开发者

Late binding for const attributes in C++ classes?

I know there is no late binding for class attributes. But i need a good pattern to do this:

#include <cstdlib>
#include <iostream>
using namespace std;

class B
{
public:
    const int i;
    B() : i(1) {}
};

class D : public B
{
public:
    const int i;
    D() : i(2) {}
};


int main()
{
    D d;
    B *ptr = &d;

    cout << ptr->i << endl;

    return 0;
}

Output is 1, but I expected 2. I guess, i should use a different pattern. 开发者_如何学GoAny suggestion?


The version of i that gets output is dependent on the compile-time type definition. You've defined two different variables, so you'll get two different results. The way to fix this is to make sure there's only one version of the variable. You can use a contructor in B to initialize the const variable.

class B
{
public:
    const int i;
    B() : i(1) {}
protected:
    B(int j) : i(j) {}
};

class D : public B
{
public:
    D() : B(2) {}
};


You'll need to use a virtual method, just like all late binding in C++.

class B
{
public:
    virtual int get_i() const { return 1; }
};

class D : public B
{
public:
    virtual int get_i() const { return 2; }
};


You're confusing the data members B::i (initialized to 1) and D::i (initialized to 2). They aren't the same, and calls through a B * will get B::i, not D::i.

In order to get polymorphic behavior, you'll need to use virtual functions. (Another approach is in Mark Ransom's answer.)


You're just adding new members to the derived class, which also happen to hide the members of the base class. That's not what you want. Instead, use a virtual function:

class B
{
  int m_i;
public:
  virtual ~B() { }
  virtual int get() const { return m_i; }
};

class D : public B
{
  int m_j;
public:
  virtual int get() const { return m_j; }
};

Usage:

D d;
B & b = d;
std::cout << b.get() << std::endl;  // correct dynamic dispatch


Virtual dispatch works on function members, but not data members.

If you desperately need the same-named variable in both classes, then you can use an accessor function to do the job:

#include <cstdlib>
#include <iostream>
using namespace std;

class B
{
    const int i;
public:
    B() : i(1) {}
    virtual int getI() { return i; }
};

class D : public B
{
    const int i;
public:
    D() : i(2) {}
    virtual int getI() { return i; }
};


int main()
{
    D d;
    B* ptr = &d;

    cout << ptr->getI() << endl;
}

// Output: 2

Live demo.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜