2017-03-06 40 views
0

我们正在试图命名空间我们与命名空间API的版本继承问题,虽然我们计算过,我们会得到一些问题,虚函数:C++使用的版本命名空间可能会导致覆盖

namespace v1 { 
    class someParam { 
    public: 
     someParam() {}; 
     virtual ~someParam() {}; 
    }; 

    class someClass { 
    public: 
     someClass() {}; 
     virtual ~someClass() {}; 
     virtual bool doSomething(someParam a); 
    }; 


    bool someClass::doSomething(someParam a) 
    { 
     return true; 
    } 
} 

namespace v2 { 

    class someParam : public v1::someParam { 
    public: 
     bool doParamStuff(); 
    }; 
    bool someParam::doParamStuff() 
    { 
     return true; 
    } 
} 

// Type Aliasing for v2 API 
using someClass = v1::someClass; 
using someParam = v2::someParam; 

// SOME OTHER PROGRAM 
class plugin : public someClass 
{ 
public: 
    plugin() {}; 
    virtual ~plugin() {}; 
    bool doSomething(someParam a) override; 

}; 

在这在特定情况下,我们正在创建现有类的扩展以实现二进制兼容性。虽然,由于override关键字,我们得到了plugin :: doSomething的编译错误,因为它不覆盖someClass :: doSomething,因为:

plugin :: doSomething(v2 :: someParam)vs someClass :: doSomething(v1 :: someParam)。

有没有什么办法可以修正插件而不明确地在插件类中使用v1 for someParam?理想的情况下,没有什么应该在插件方面来完成,而无需创建V2 :: SomeClass的

回答

0

此:

virtual bool doSomething(::v1::someParam a) 

指定一个二进制文件(和C++)接口。你不能用它覆盖它

virtual bool doSomething(::v2::someParam a) 

因为这是不同的类型。它们不兼容。这些签名是无关的。

当您更新someParam,你还必须更新使用someParam每一个接口,然后使用这些接口的每个接口等

所以,在namespace v2

class someClass: ::v1::someClass { 
public: 
    virtual bool doSomething(::v1::someParam a) override final; 
    virtual bool doSomething(someParam a); 
}; 

doSomething(v1::someParam)描述如何生成v2::someParam并将其传递给新的doSomething

如果你不能做到这一点,你不是必须这样做:

class someClass { 
public: 
    virtual bool doSomething(someParam a); 
}; 

,并v2::someClass类型无关v1::someClass

无论如何,你做

using someClass = v2::someClass; 

现在,而不是使用using声明,可以改为conditually使用inline namespace秒。

更新版本时,使当前版本为inline命名空间。其他的是正常的命名空间。

现在,代码将默默开始使用“当前”的inline namespace

您可以从以前的命名空间导入类型using symbol = ::library_ns::v1::symbol;只有当该类型保持不变时才能完成此操作,以及其所有参数。现在


,如果你的::v2::someParam只有一个帮手,你可以从someParamInstance类型划分someParamArg。然后

someParamArg将是someParam层次结构(::v1::someParam)的根的参数类型,而someParamInstance::v2::someParam;当人们想要使用它时应该创建什么。

在这种情况下,someParamArg需要能够考虑状态someParamInstance,即使是那些从更高版本。因此,这只适用于如果::v2::someParam本质上是帮助者,或者它支持内部值类型多态性。