通过 C++ 中的重载构造函数初始化未知类型的变量

Tom*_*Tom 22 c++ constructor overloading initialization auto

主要来自 Python 背景,我在使用 C++ 类型时有些挣扎。

我试图通过将不同类型作为参数的几个重载构造函数之一来初始化一个类变量。我已经读过使用auto关键字可以用于变量的自动声明,但是在我的情况下,它不会被初始化,直到选择了构造函数。然而,编译器对不初始化不满意value

class Token {
public:

    auto value;

    Token(int ivalue) {
        value = ivalue;
    }
    Token(float fvalue) {
        value = fvalue;
    }
    Token(std::string svalue) {
        value = svalue;
    }

    void printValue() {
        std::cout << "The token value is: " << value << std::endl;
    }
};
Run Code Online (Sandbox Code Playgroud)

在 python 中,这可能如下所示:

class Token():
        def __init__(self, value):
             self.value = value

        def printValue(self):
             print("The token value is: %s" % self.value)
Run Code Online (Sandbox Code Playgroud)

auto在这种情况下使用关键字的正确方法是什么?我应该完全使用不同的方法吗?

eer*_*ika 17

通过 C++ 中的重载构造函数初始化未知类型的变量

C++ 中没有“未知类型的变量”这样的东西。

在这种情况下使用 auto 关键字的正确方法是什么?

自动推导的变量具有从初始化器推导的类型。如果没有初始化程序,则不能使用 auto。auto 不能用于非静态成员变量。类的一个实例不能与另一个实例具有不同类型的成员。

在这种情况下无法使用 auto 关键字。

我应该完全使用不同的方法吗?

大概。看起来您正在尝试实现一个std::variant. 如果您需要一个变量来存储 X 种类型中的一种,那么您应该使用它。

但是,您可能正在尝试在 C++ 中模拟动态类型。虽然您可能因使用过 Python 而熟悉它,但在许多情况下这并不是理想的方法。例如,在这个特定的示例程序中,您对成员变量所做的一切就是打印它。所以在每种情况下存储一个字符串会更简单。其他方法是如 Rhathin 所示的静态多态性或如 Fire Lancer 所示的OOP 风格的动态多态性


小智 11

C++ 是一种静态类型语言,这意味着所有变量类型都在运行之前确定。因此,auto关键字不同于var动态类型语言 javascript 中的关键字。auto关键字通常用于指定不必要的复杂类型。

您正在寻找的可能是通过使用 C++ 模板类来完成的,它允许创建采用不同类型的类的多个版本。

此代码可能是您正在寻找的答案。

template <typename T>
class Token {
private:
    T value;

public:
    Token(const T& ivalue) {
        value = ivalue;
    }

    void printValue() {
        std::cout << "The token value is: " << value << std::endl;
    }
};
Run Code Online (Sandbox Code Playgroud)

如果满足某些条件,则此代码将编译,例如operator<<应为 std::ostream& 定义函数并键入 T。


Rha*_*hin 6

与其他人提出的不同的方法是使用模板。下面是一个例子:

template<class T>
class Token {
public:

    T value;

    Token(T value) :
        value(std::move(value))
    {}

    void printValue() {
        std::cout << "The token value is: " << value << std::endl;
    }
};
Run Code Online (Sandbox Code Playgroud)

然后你可以像这样使用你的类:

Token<int> x(5);
x.printValue();
Run Code Online (Sandbox Code Playgroud)