我有以下抽象类
class Language {
const std::string name ;
protected:
std::string cmd, home ;
Config::Section cfg ;
bool load_conf() {
home = env("HOME") ;
// DEBUG
std::cout << home << std::endl ;
std::cout << name << std::endl ;
if (!cfg.load(home + "/.cr", name)) {
std::cerr << "cr: No configuration found for this language." << std::endl ;
return false ;
}
return true ;
}
public:
virtual bool handles(const std::string) = 0 ;
virtual int run(std::string) = 0 ;
} ;
和许多实现它的派生类
class Python : public Language {
const std::string name ;
public:
Python() : name("python") {}
bool handles(const std::string) ;
int run(std::string) ;
};
我遇到的问题是load_conf()
因某种原因导致name
为空,这使得即使配置正常也会发出错误。从load_conf()
调用run()
,由每个派生类实现。
我尝试过name
受保护和公开,但似乎没有任何区别。理想情况下,我只想在抽象类中声明name
(作为受保护的),而不必在每个派生类中重复声明,但是当我尝试它时,它将无法编译。我也尝试使用this->name
,但这也是空的,删除const
也没有任何区别。
我觉得这是一个范围问题,但我错过了什么?
答案 0 :(得分:6)
在基类中声明一个构造函数,该构造函数接受一个参数,即初始化name
的值,并在派生的ctors中传递它。
这是一个例子:
class Language {
const std::string name ;
};
class Python : public Language {
const std::string name ; // <-- this is different, and frankly redundant
};
以下内容应取代上述......
class Language {
const std::string name ;
Language(std::string some_name) : name(some_name) {} // <-- set the name
};
class Python : public Language {
Python() : Language("python") {} // construct the base with the name...
};
答案 1 :(得分:1)
您在Base类name
中已经有一个名为Language
的变量当您在name
内引用load_conf()
时,编译器会引用基类name
变量而不是派生类name
变量。
简单的解决方案是为两个变量或
具有单独的名称
将Base类中的name
设为protected
,以便每个派生类都可以引用此变量。
答案 2 :(得分:0)
在您的class Python
中,您覆盖的字段name
不是load_conf
引用的字段。
在name
类Language
中设置protected
并删除其子类中的{{1}},它应该可以正常运行。