C++含基类vector成员类的模板、初始化列表构造器及多态实现问询
C++ 持有基类vector成员的Stan类实现方案
完整可运行代码
#include <iostream> #include <string> #include <vector> #include <memory> #include <initializer_list> #include <utility> using namespace std; class Element { public: string naziv; double obujam; static int brV; Element(string n, double o) : naziv(n), obujam(o) { if (o > 3.) brV++; } int getVelikiElementi(){ return brV; } virtual void GetVrsta(){ cout << "Vrsta Stana: Osnovni element" << endl; } virtual ~Element() = default; }; int Element::brV = 0; namespace Zgrada { class Stan : public Element { public: vector<unique_ptr<Element>> Elementi; // 可变参数模板构造函数:支持传入任意数量Element派生类对象 template<typename... Args> Stan(string naziv, double obujam, Args&&... args) : Element(naziv, obujam) { (Elementi.emplace_back(make_unique<decay_t<Args>>(forward<Args>(args))), ...); } // initializer_list构造函数 Stan(string naziv, double obujam, initializer_list<unique_ptr<Element>> list) : Element(naziv, obujam) { for (auto& item : list) { Elementi.push_back(move(const_cast<unique_ptr<Element>&>(item))); } } void GetVrsta() override { cout << "Vrsta Stana: Standardan stan" << endl; } void prikaziSveElemente() { cout << "Stan " << naziv << " sadrzi sljedece elemente:" << endl; for (auto& e : Elementi) { e->GetVrsta(); } } }; // 派生类Apa class Apa : public Stan { public: Apa(string naziv, double obujam) : Stan(naziv, obujam) {} void GetVrsta() override { cout << "Vrsta Stana: Apartman" << endl; } }; // 派生类Gar class Gar : public Stan { public: Gar(string naziv, double obujam) : Stan(naziv, obujam) {} void GetVrsta() override { cout << "Vrsta Stana: Garaza" << endl; } }; } int main () { // 演示1:调用模板构造函数 Zgrada::Stan stan1("Stan 1", 50.5, Zgrada::Apa("Jednosoban apartman", 30.2), Zgrada::Gar("Garaza za jedno auto", 15.8), Element("Pogreb", 4.2) ); stan1.prikaziSveElemente(); cout << endl; // 演示2:调用initializer_list构造函数 Zgrada::Stan stan2("Stan 2", 65.3, { make_unique<Zgrada::Apa>("Dvosoban apartman", 45.1), make_unique<Zgrada::Gar>("Garaza za dva auta", 22.4), make_unique<Element>("Balkon", 3.5) }); stan2.prikaziSveElemente(); cout << endl; // 演示3:多态效果验证 Element* elem1 = new Zgrada::Apa("Test apartman", 35.0); Element* elem2 = new Zgrada::Gar("Test garaza", 18.0); elem1->GetVrsta(); elem2->GetVrsta(); delete elem1; delete elem2; return 0; }
实现说明
- 修复了原代码的对象切片问题:使用
unique_ptr<Element>智能指针存储基类对象,支持多态调用的同时避免内存泄漏 - Stan类完整放入
Zgrada命名空间,符合要求 - 可变参数模板构造函数采用C++17折叠表达式实现,支持任意数量的Element派生类对象传入初始化
- initializer_list构造函数支持批量传入元素初始化成员vector
- Apa、Gar两个派生类重写了虚函数
GetVrsta,通过基类指针调用时会自动匹配对应派生类的实现,完成多态演示
内容的提问来源于stack exchange,提问作者Ofca
相关产品推荐
相关产品推荐

