需要的指导:从抽象基类派生类的unique_ptr向量

时间:2014-05-06 14:56:28

标签: c++ winapi vector abstract-class unique-ptr

我正在尝试简化我的代码并使其更好,更轻松地工作:

这意味着潜入向量和unique_ptr,我已经阅读了很多好东西。但是,它们对我来说是全新的。我已经阅读了两篇关于这两页的内容,但它还有很多内容可以解决。

我目前正在做的是以传统方式创建抽象类的对象:

VirtualBaseClass* foo1= new DerviedClass1; 
VirtualBaseClass* foo2= new DerviedClass2;
VirtualBaseClass* foo3= new DerviedClass3;

但是因为我有3个 - 而且很可能会有更多 - 我想让它们更容易在它们之间切换,因为我将比较每个程序运行的对象的任何组合。

目前,为了切换,我只是重命名我想要实例化一个对象的DerviedClass,所以我不必用foo3等重命名每个foo1。

VirtualBaseClass* Generic1 = new DerviedClass3;
VirtualBaseClass* Generic2 = new DerviedClass1;

但最终我希望用户告诉程序要比较哪两个对象。所以一个好的起点似乎使它成为VirtualBaseClass的一个数组,但是从研究来看,删除数组似乎很痛苦,所以人们建议使用智能指针和向量。

所以我试着同时使用它们。对于我做的独特指针

unique_ptr<vBaseClass*> foo1(DerviedClass1);
unique_ptr<vBaseClass*> foo2(DerviedClass2);
unique_ptr<vBaseClass*> geneic1 = move(foo1);

然而,从我读到的我应该做的事情

unique_ptr<vBaseClass*> foo1(new DerviedClass1);

但是new给出了specfier类型的错误,但是因为它没有它,所以我没想到它。 使用move(foo1)我得到一个错误,没有移动,例如重载函数匹配和编译一大堆其他错误,如

unique_ptr<vBaseClass*> champ1 = move(foo1);

错误C3867:'Controller :: foo1':函数调用缺少参数列表;使用'&amp; Controller :: foo1'创建指向成员的指针  错误C2780:'_ OutTy * std :: move(_InIt,_InIt,_OutTy(&amp;)[_ OutSize])':需要3个参数 - 提供1个

所有这些都是在我的Controller.h文件中完成的。 我迫切需要指导。我不知道我在做什么甚至是笨蛋,我是否需要使用这个载体?我怎么会开始呢?有没有更好的方法呢?我如何让用户告诉程序使用哪个对象?对于数组,它将为foo1输入0或为foo2输入1但是使用向量?有没有更好的办法?

我的实际代码

#pragma once
#include "stdafx.h"
#include "Skarner.h"
#include "MasterYi.h"
#include "Riven.h"


using namespace std;
class Controller
{
public:
    Controller();
    ~Controller();
    double PCFreq;
    __int64 CounterStart;
    int CounterCheck;
    ofstream out;
    Champion* skarner = new Skarner;//old way of doing it
    //Champion* yi = new MasterYi;//old way of doing it
    //Champion* riven = new Riven;//old way of doing it
    //Champion** champions = new Champion*[200];
    //Champion[0] = new Skarner();
    //unique_ptr<Champion> skarner(Skarner);
    unique_ptr<Champion> yi(new MasterYi);// doesn't work new error
    unique_ptr<Champion*> riven(Riven); //works with or without *
    unique_ptr<Champion*> champ1 = move(riven)//error with move

    vector<unique_ptr<Champion>> pChampions;//vector of pointers to champion
    //unique_ptr<Champion> champ2;
    //Champion *champ1 = dynamic_cast<Champion*>(yi);
    //Champion *champ2 = dynamic_cast<Champion*>(skarner);//not sure what the signficance of this is
//Leaving some methods out 
};

哇所以显然你不能只在cpp文件中使用头文件中的“new”。但是我现在仍然不确定如何在控制器中使用它来充分利用它?我真的希望它作为成员变量/实例变量。

尝试这样做。在controller.h中

shared_ptr<Champion> yi;
shared_ptr<Champion> riven;
shared_ptr<Champion> skarner;
shared_ptr<Champion> champ1;
shared_ptr<Champion> champ2;

并在.cpp中定义它们

Controller::Controller()
{
    PCFreq = 0.0;
    CounterStart = 0;
    out.open("finalStats.txt");
    CounterCheck = 0;
    yi = shared_ptr<Champion> (new MasterYi);
    riven = shared_ptr<Champion>(new Riven);
    skarner = shared_ptr<Champion>(new Skarner);
    champ1 = move(yi);
    champ2 = move(riven);

}

上面的代码现在似乎有效,但我没有看到任何直接的好处。

2 个答案:

答案 0 :(得分:1)

解释

你得到了*

unique_ptr<vBaseClass> foo1(new DerivedClass1);

应该通过分配具有动态存储持续时间的新DerivedClass1并在foo1中存储指向它的指针来实现这一目的。

提醒一下,只需大声朗读类型:foo1类型为&#34;唯一指向vBaseClass&#34;。

对于评论中的人群

以下显示了原始指针和唯一指针之间的使用差异:

{
    int* a = new int(42);
    unique_ptr<int> b(new int(42));
    std::cout << *a << ", " << *b << "\n";
    delete a;
}

没有进一步的区别。如果没有进一步的信息,您遇到的任何其他问题都与难以确定的其他问题有关。

此外,unique_ptr<Champion*> riven(Riven);是函数的函数声明,其名称为riven,返回unique_ptr<Champion*>并采用类型Riven的单个参数。这不是错误的原因是因为它根本不符合你的想法。

最后,绝对没有什么能使标题变得特别。事实上,C ++在解析之前执行文本替换,因此实际的解析器甚至不知道代码来自何处!

Karmic Demonstration

代码:

struct champ { virtual std::string whoami() = 0; };
struct karma : champ { std::string whoami() override { return "karma"; } };

int main() {
    champ* a = new karma;
    std::unique_ptr<champ> b(new karma);
    std::cout << a->whoami() << ", " << b->whoami() << "\n";
}

结果:

karma, karma

Proof

答案 1 :(得分:0)

unique_ptr<Champion> yi(new MasterYi);// doesn't work new error看起来像编译器的函数声明,new在该上下文中无效。

unique_ptr<Champion*> riven(Riven); //works with or without * 看起来像一个函数声明,无论是否有*都有效。

unique_ptr<Champion*> champ1 = move(riven)//error with move您无法将move函数转换为unique_ptr

我很难理解你的问题,但也许你的意思是:

unique_ptr<Champion> yi = new MasterYi;
unique_ptr<Champion> riven = new Riven;
std::vector<std::unique_ptr<Champion> > pChampions = { new Skarner };