You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何判断C++类对象使用了哪个构造函数重载?

如何判断C++重载构造函数创建的对象的存储类型

你直接访问var.ExampleChar报错是因为ExampleChar是类的私有成员,C++的封装机制禁止类外部直接访问私有成员,必须通过类提供的公共接口来访问。

同时你的类当前设计存在问题:不管用哪个构造函数创建对象,两个成员变量ExampleDouble和ExampleChar都会存在,但只有一个被初始化,另一个处于未定义状态,不仅没法区分类型,还可能触发未定义行为。以下是几种可行的解决方法:

方法1:添加类型标记与查询接口

在类中新增一个标记变量记录当前对象的初始化类型,同时提供公共方法查询标记、获取对应成员值。

#include <iostream>

class example
{
    double ExampleDouble;
    char ExampleChar;
    enum class Type { Double, Char };
    Type type_;

public:
    // 初始化列表构造,避免未定义成员
    example(double ED) : ExampleDouble(ED), type_(Type::Double) {}
    example(char EC) : ExampleChar(EC), type_(Type::Char) {}

    // 查询类型的公共接口
    bool isDouble() const { return type_ == Type::Double; }
    bool isChar() const { return type_ == Type::Char; }

    // 安全获取成员的接口
    double getDouble() const { return ExampleDouble; }
    char getChar() const { return ExampleChar; }
};

int main()
{
    example var('a');
    if (var.isChar()) {
        std::cout << "存储的是char类型:" << var.getChar() << std::endl;
    } else if (var.isDouble()) {
        std::cout << "存储的是double类型:" << var.getDouble() << std::endl;
    }
    return 0;
}

方法2:使用std::variant重构(C++17及以上)

用std::variant存储二选一的类型,它原生支持判断存储类型,还能避免同时占用两个成员的内存空间。

#include <iostream>
#include <variant>

class example
{
    std::variant<double, char> data_;

public:
    example(double ED) : data_(ED) {}
    example(char EC) : data_(EC) {}

    // 暴露数据访问接口,也可以封装成更友好的查询方法
    const std::variant<double, char>& getData() const { return data_; }
};

int main()
{
    example var('a');
    const auto& data = var.getData();
    if (std::holds_alternative<char>(data)) {
        std::cout << "存储的是char类型:" << std::get<char>(data) << std::endl;
    } else if (std::holds_alternative<double>(data)) {
        std::cout << "存储的是double类型:" << std::get<double>(data) << std::endl;
    }
    return 0;
}

方法3:利用多态(适合复杂扩展场景)

将example设计为抽象基类,派生对应类型的子类,通过多态判断对象类型,适合需要扩展更多存储类型的场景。

#include <iostream>
#include <memory>
#include <stdexcept>

class example
{
public:
    virtual ~example() = default;
    virtual bool isDouble() const = 0;
    virtual bool isChar() const = 0;
    virtual double getDouble() const = 0;
    virtual char getChar() const = 0;
};

class DoubleExample : public example
{
    double value_;
public:
    DoubleExample(double val) : value_(val) {}
    bool isDouble() const override { return true; }
    bool isChar() const override { return false; }
    double getDouble() const override { return value_; }
    char getChar() const override { throw std::logic_error("对象不是char类型"); }
};

class CharExample : public example
{
    char value_;
public:
    CharExample(char val) : value_(val) {}
    bool isDouble() const override { return false; }
    bool isChar() const override { return true; }
    double getDouble() const override { throw std::logic_error("对象不是double类型"); }
    char getChar() const override { return value_; }
};

int main()
{
    std::unique_ptr<example> var = std::make_unique<CharExample>('a');
    if (var->isChar()) {
        std::cout << "存储的是char类型:" << var->getChar() << std::endl;
    } else if (var->isDouble()) {
        std::cout << "存储的是double类型:" << var->getDouble() << std::endl;
    }
    return 0;
}

内容的提问来源于stack exchange,提问作者yes

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 23:53:11