抽象类成员无法访问派生类中的值集

时间:2012-01-16 13:55:01

标签: c++ g++

我有以下抽象类

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也没有任何区别。

我觉得这是一个范围问题,但我错过了什么?

3 个答案:

答案 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引用的字段。

nameLanguage中设置protected并删除其子类中的{{1}},它应该可以正常运行。