不使用模板访问构造函数中的重写字段 我不能从父类C++构造函数访问子类中覆盖的字段,并且我不能使用模板,因为上游项目不使用它们。 这是我在C++中尝试实现的Python原型。代码包含两个驱动程序类-一个子类和一父类,父类在初始化期间打印类的name class Driver(object): name = "Unknown" def __init__(self): print(self.name) class SpecificDriver(Driver): name = "Specific" def __init__(self): super(SpecificDriver, self).__init__() Driver() SpecificDriver()

不使用模板访问构造函数中的重写字段 我不能从父类C++构造函数访问子类中覆盖的字段,并且我不能使用模板,因为上游项目不使用它们。 这是我在C++中尝试实现的Python原型。代码包含两个驱动程序类-一个子类和一父类,父类在初始化期间打印类的name class Driver(object): name = "Unknown" def __init__(self): print(self.name) class SpecificDriver(Driver): name = "Specific" def __init__(self): super(SpecificDriver, self).__init__() Driver() SpecificDriver(),python,c++,inheritance,overriding,Python,C++,Inheritance,Overriding,这会将两个字符串打印到控制台 Unknown Specific 看起来C++中无法访问重写名称,因为在这个点上不存在名称。所以,也许有另一种方法可以在初始化时打印驱动程序name 更新(2018)< /强>:这个问题的原始标题是“C++中没有模板的初始化时打印重写的子字段”,它被关闭得太宽了。假设您有两个类基并派生,基构造函数对派生类一无所知,这使得我们无法区分这两种类型 由于您也不能(不应该)在构造函数中调用虚拟方法,因此一种常见的模式是创建init方法: struct Base {

这会将两个字符串打印到控制台

Unknown
Specific

看起来C++中无法访问重写<代码>名称<代码>,因为在这个点上不存在<代码>名称<代码>。所以,也许有另一种方法可以在初始化时打印驱动程序

name


<强>更新(2018)< /强>:这个问题的原始标题是“C++中没有模板的初始化时打印重写的子字段”,它被关闭得太宽了。

假设您有两个类基并派生,基构造函数对派生类一无所知,这使得我们无法区分这两种类型

由于您也不能(不应该)在构造函数中调用虚拟方法,因此一种常见的模式是创建init方法:

struct Base {
    virtual std::string get_name() { return "Base"; }
    void init() { std::cout << get_name(); }
};

struct Derived : public Base {
    virtual std::string get_name() { return "Derived"; }
};

// Later on ..
Base b;
b.init(); // Should print "Base"

Derived d;
d.init(); // Should print "Derived"
struct Base{
虚拟std::字符串get_name(){返回“Base”;}

void init(){std::cout尽管您要求在没有模板的情况下执行此操作,但这是从基类构造函数执行此操作的唯一方法

下面是一个应如何完成的示例:

struct IDriver {
    // Public virtual API:
    virtual void func1() = 0;
    // ...
    virtual ~IDriver() {}
};

template<typename Derived>
class Driver : public IDriver {
public:
    Driver() {
         std::cout << "Driver" << std::endl;
         std::cout << static_cast<Derived*>(this)->name() << std::endl;
    }   
};

class SpecificDriver : public Driver<SpecificDriver> {
public:
    // Public virtual API:
    virtual void func1();
    std::string name() const { return "SpecificDriver"; }
    // or use typeid(SpecificDriver).name() if you prefer
};

int main() {
    SpecificDriver sd;
}

甚至可以简化使用
typeid()

#包括
#包括
#包括
模板
类驱动程序{
公众:
司机(){

std::您可以使用静态多态性,也就是CRTP。@πάντα吗ῥεῖ 这需要使用模板吗?在代码库中,我正在修补,但我看不到它们,而且看起来一点都不简单。是的,这需要使
Driver
成为一个以派生类为类型参数的模板化基类。因此,您可以使用
static\u cast(此)
每个你想访问
特定驱动程序成员的地方。非常简单。我不明白你为什么不能使用模板。你说“因为上游不使用模板”是什么意思?@πάνταῥεῖ 我试图修补此项目以进行调试,代码不使用模板-我试图在类初始化中使用新的
init
方法,但它不起作用,可能是因为它没有创建-可能有一种方法可以访问派生类的静态属性?为什么不可能定义“Base”和“derived”作为类属性而不是方法?是否可以使用@tobspr方法中的附加
init()
函数,但将
name
作为字段而不是函数调用?
template<typename Derived>
class Driver : public IDriver {
public:
    Driver() {
         std::cout << name << std::endl;
         std::cout << Derived::name << std::endl;
    }   

private:
    static const std::string name;
};

template<typename Derived>
const std::string Driver<Derived>::name = "Driver";

class SpecificDriver : public Driver<SpecificDriver> {
public:
    static const std::string name;
};

const std::string SpecificDriver::name = "SpecificDriver";

int main() {
    SpecificDriver sd;
}
#include <iostream>
#include <string>
#include <typeinfo>

template<typename Derived>
class Driver {
public:
    Driver() {
         std::cout << typeid(*this).name() << std::endl;
         std::cout << typeid(Derived).name() << std::endl;
    }  
};

class SpecificDriver : public Driver<SpecificDriver> {
};

int main() {
    SpecificDriver sd;
}