基于initializer_list构造支持多态与内联构造的非const值map
没问题,咱们来实现一个完全符合你所有要求的map。核心是用智能指针来存储多态对象——直接存类对象会触发切片问题,而智能指针既能保留多态特性,又能自动管理内存,完美匹配你的需求。
先上完整代码示例:
#include <iostream> #include <map> #include <memory> struct foo { virtual void print() { std::cout << "foo"; } }; struct bar : foo { virtual void print() { std::cout << "bar"; } }; int main() { // 直接用initializer_list构造目标map std::map<int, std::unique_ptr<foo>> my_map = { {1, std::make_unique<foo>()}, {2, std::make_unique<bar>()} }; // 验证多态性和非const特性 for (auto& entry : my_map) { entry.second->print(); // 多态调用:1输出foo,2输出bar // 如果foo有非const成员函数,比如void setVal(int),也能直接调用: // entry.second->setVal(42); std::cout << "\n"; } // 完全不需要手动清理内存,unique_ptr会自动处理 return 0; }
接下来逐个对应你的要求,看看怎么满足:
- 值具备多态性:用
std::unique_ptr<foo>作为map的值类型,指针可以指向foo或它的派生类bar,调用虚函数print()时会自动触发对应类的实现,完美保留多态行为。 - 值为非const类型:
std::unique_ptr<foo>指向的是非const对象,你可以自由调用对象的非const成员函数(如果有的话),完全符合要求。 - 通过initializer_list构造:直接用
{ {1, make_unique<foo>()}, {2, make_unique<bar>()} }初始化列表构造map,没有额外的转换步骤。 - 在initializer_list内部构造值:每个
std::make_unique<foo>()和std::make_unique<bar>()都是在初始化列表内部直接构造出对应的对象,并包装成智能指针,所有构造逻辑都在列表里完成。 - 无需辅助函数、lambda或宏:全程只用了标准库的
std::map、std::unique_ptr和std::make_unique,没有任何自定义的辅助工具。 - 不需要单独清理函数:
std::unique_ptr会在map销毁(比如离开main函数作用域)时自动释放所指向的对象,完全不需要手动delete或者专门的清理逻辑。
如果你的环境是C11(std::make_unique是C14引入的),可以把初始化列表里的make_unique换成直接构造unique_ptr,效果完全一样:
// C++11兼容版本的初始化方式 std::map<int, std::unique_ptr<foo>> my_map = { {1, std::unique_ptr<foo>(new foo())}, {2, std::unique_ptr<foo>(new bar())} };
内容的提问来源于stack exchange,提问作者Jonathan Mee
相关产品推荐
相关产品推荐

