【问题标题】:C++ Inlining of virtually inherited functions虚拟继承函数的 C++ 内联
【发布时间】:2013-10-22 20:07:05
【问题描述】:

好的,这更像是要求澄清 C++ 的功能是如何工作的,而不是回答是否可以。我将首先解释我遇到的问题,因为直接的答案是它不是一个很好的类设计。

我有一个类正在形成一个不可维护的 if 语句块;当我尝试将其转换为复合对象时,我开始对如何让深层副本工作而不是原始 blob 以及一般的小对象分配问题感到更加困惑。因此,我开始寻找一种方法将 blob 拆分为几个类,编译器可以将它们转换回原始 blob。

在下面的代码中,我知道foo_bfoo_c 中的super::get_x() 是可内联的——来自其他堆栈溢出问题——但我不确定foo_c 中的super::get_z() 是否是。最后对f.get_x()f.get_y()f.get_z() 的调用是否是虚函数调用,因为它不是显式的,并且它不知道foo 是否有子类,或者它们是否可以内联因为它,事实上,没有?

namespace PRIVATE {

class foo_a 
{
    int x, y, z;
public:
    foo_a(int X, int Y, int Z)
    {
        x = X; y = Y; z = Z;
    }
    virtual ~foo_a() { }

    virtual void update() { };

    virtual int get_x() const { return x; } 
    virtual int get_y() const { return y; }
    virtual int get_z() const { return z; }
};

class foo_b : public virtual foo_a 
{
typedef foo_a super;
    unsigned char c_0,c_1,c_2, mod;

public:
    foo_b(int X, int Y, int Z) : foo_a(X, Y, Z)
    {
        c_0 = c_1 = c_2 = mod = 0;
    }
    virtual ~foo_b() { }

    void activate_b()
    {
        c_2 = c_1;
        c_1 = c_0;
        c_0 = 5;

        mod = c_0? 1 + (c_1? 1 + (c_2? 1 : 0) : 0) : 0;
    }

    virtual void update()
    {
        super::update();

        if(c_0) { --c_0; mod = 1;
        if(c_1) { --c_1; mod = 2;
        if(c_2) { --c_2; mod = 3; }}};
    }
    virtual int get_x() const { return super::get_x() + mod; };
    virtual int get_y() const { return super::get_y() - mod; };
};

class foo_c : public virtual foo_b 
{
typedef foo_b super;
    bool active;

public:
    foo_c(int X, int Y, int Z) : foo_b(X, Y, Z)
    {
        active = false;
    }
    virtual ~foo_c() { }

    bool activate_c(bool X) { return (active = X); }

    virtual int get_x() const 
    { 
        int t = super::get_x();
        return active? t % 8 : t;
    }
    virtual int get_z() const 
    { 
        int t = super::get_z();
        return active? t % 8 : t;
    }
};

}

class foo : public virtual PRIVATE::foo_c 
{
public:
    foo(int X, int Y, int Z) : PRIVATE::foo_c(X, Y, Z) { }
    virtual ~foo() { }
};


int main(int argc, const char * argv[])
{
    foo * f = new foo(4, 6, 8);
    f->activate_b();
    f->get_x();
    f->get_y();
    f->get_z();

    delete f;

    return 0;
}

【问题讨论】:

  • 我会让其他人详细回答,但一般来说,大多数编译器都是这样工作的:无法静态解析(在编译时)的调用永远不会内联。如果函数有可能被覆盖,则不能内联。

标签: c++ inheritance virtual inline


【解决方案1】:

查看C++ FAQ

因此,只有当编译器知道作为虚函数调用目标的对象的“确切类”时才能内联内联虚调用。仅当编译器具有实际对象而不是指针或对象引用时,才会发生这种情况。即,使用本地对象、全局/静态对象或组合内的完全包含对象。

【讨论】:

  • 如果类或虚函数是final
猜你喜欢
  • 2015-06-21
  • 2016-03-26
  • 2011-01-08
  • 1970-01-01
  • 2015-09-01
  • 2017-03-31
相关资源
最近更新 更多