【发布时间】:2017-07-23 11:20:04
【问题描述】:
我正在尝试使用抽象类,但在定义派生类的构造函数时遇到了一些问题。我根据question的答案编写了以下代码。
#include <string>
#include <iostream>
class ICommand {
private:
ICommand();
public:
const std::string name;
ICommand(const std::string& name) : name(name) { }
virtual void callMe();
virtual void callMe2();
};
class MyCommand : public ICommand {
public:
int x;
MyCommand(const std::string& name) : ICommand(name) { }
MyCommand(const std::string& name, int x) : ICommand(name), x(x) { }
void callMe() {
std::cout << name << "\n";
}
void callMe2() {
std::cout << name << x << "\n";
}
};
void f(std::string name) {
MyCommand A(name);
A.callMe();
}
这编译没有错误。但是我的目标是为 R 包构建一个 .so )。在 R 安装过程中,.so 构建没有错误,clang++ -shared,但随后有一个验证步骤会产生
unable to load shared object '/path/object.so':
/path/object.so: undefined symbol: _ZTI8ICommand
我以前遇到过这种问题,并且有一些变通方法 - 不调用 Icommand(name) 相当简单,但我想了解那里发生了什么,以及如果可能的话,如何避免变通方法。
提前感谢您的想法。
回答
为了方便以后的读者:这里唯一需要的改动就是把抽象类中虚函数的定义替换为
virtual void callMe() = 0;
virtual void callMe2() = 0;
这使它们成为纯虚函数。为什么这完全解决了问题。
【问题讨论】:
-
您需要为
ICommand默认构造函数提供定义。 -
@Ron 我没有代码(这是 R 安装过程的一部分),但事实是共享对象似乎不正确。
-
@Ron 在哪里?抱歉,如果我遗漏了什么,但我只看到默认 ctor 的声明而不是定义。
-
@Elvis 你可以尝试删除
ICommand的默认构造函数的声明吗?它默认被删除,因为你的构造函数删除了它。 -
@Elvis "如果类 X 没有用户声明的构造函数,则没有参数的非显式构造函数被隐式声明为默认值" 来自
[class.ctor]/4-> 没有隐式默认构造函数的类带任何参数的构造函数
标签: c++ inheritance shared-libraries abstract-class r-package