基类构造函数对派生类C++不可见
Base class constructor not visible to derived class C++
我正在用C++编写一个玩具正则表达式引擎作为学习练习,但我遇到了编译器错误。下面是实现不同表达式子类型的类的定义:
// ***************************************************************
// ***************************************************************
class RegexExpression {
public:
virtual RegexResult match(std::string);
};
// ***************************************************************
class RegexTerm : public virtual RegexExpression {
public:
RegexTerm(char c) : _matchChar(c) {}
RegexResult match(std::string);
private:
char _matchChar;
};
// ***************************************************************
class RegexNil : public virtual RegexExpression {
public:
RegexResult match(std::string);
};
// ***************************************************************
// ***************************************************************
class RegexBinaryExpression : public virtual RegexExpression {
public:
RegexBinaryExpression
(RegexExpression &lhs, RegexExpression &rhs) :
_lhs(lhs), _rhs(rhs) {}
protected:
RegexExpression _lhs;
RegexExpression _rhs;
};
// ***************************************************************
class RegexOr : public RegexBinaryExpression {
public:
RegexResult match(std::string);
};
// ***************************************************************
class RegexAnd : public RegexBinaryExpression {
public:
RegexResult match(std::string);
};
但是,当我尝试实例化正则表达式时,例如:
RegexOr regex(RegexTerm('a'), RegexNil());
然后我收到一个编译器错误,告诉我来自 RegexBinaryExpression 的 2 参数构造函数不可见。
如果我在正则表达式中显式定义构造函数,例如:
RegexOr(RegexExpression &l, RegexExpression &r) : RegexBinaryExpression(l, r) {}
然后我被告知RegexNil不能转换为RegexExpression。
我在这里做错了什么?
至少
在 C++11 之前,您肯定必须在 RegexOr
中自己实现构造函数。但是,您将其实现为采用非常量引用参数,然后尝试从临时引用参数绑定该参数,这是语言禁止的。
而是通过 const 引用(甚至可能按值)获取参数:
RegexBinaryExpression(const RegexExpression &lhs, const RegexExpression &rhs)
: _lhs(lhs)
, _rhs(rhs)
{}
RegexOr(const RegexExpression &l, const RegexExpression &r) : RegexBinaryExpression(l, r) {}
不能将临时对象传递给非常量引用参数。要使其编译,您需要将参数更改为 const 引用(或按值)。
不过你有一个更大的问题。将参数复制到 RegexBinaryExpression 的成员时,它们将存储为 RegexExpression 对象,而不是派生对象。有关派生类型的信息将丢失。这称为对象切片。
您需要动态分配正则表达式对象,并将指向它们的指针存储在类中。我会推荐智能指针。您还可以将正则表达式对象的类型存储在类、模板参数中,而不是继承层次结构中。这可能更难实现,并且有一些缺点。
相关文章:
- "error: no matching function for call to"构造函数错误
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 为什么在C++中使用私有复制构造函数与删除复制构造函数
- 选择要调用的构造函数
- 如何委托派生类使用其父构造函数?
- 构造函数正在调用一个使用当前类类型的函数
- 没有用于初始化C++中的变量模板的匹配构造函数
- 初始化具有非默认构造函数的std::数组项的更好方法
- 当从函数参数中的临时值调用复制构造函数时
- 在c++构造函数中使用随机字符串生成器
- 一对向量构造函数:初始值设定项列表与显式构造
- 从构造函数抛出异常时如何克服内存泄漏
- 我不明白为什么我声明一个空的内部结构并将其传递给构造函数
- 继承:构造函数,初始化C++11中基类的类C数组成员
- 具有默认模板类型的默认构造函数的类型推导
- 使用dynamic_cast和构造函数时出错
- 在c++中使用向量时,如何调用构造函数和析构函数
- 奇怪的构造函数行为