如何判断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
相关产品推荐
相关产品推荐

