我正在努力简化我的代码,让它工作得更好更容易:
这意味着深入研究 vector 和 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 的数组,但从研究来看,删除数组似乎很痛苦,因此人们建议使用智能指针和 vector 。
所以我尝试同时使用两者。对于独特的指针,我做
unique_ptr<vBaseClass*> foo1(DerviedClass1);
unique_ptr<vBaseClass*> foo2(DerviedClass2);
unique_ptr<vBaseClass*> geneic1 = move(foo1);
但是,根据我的阅读,我应该这样做
unique_ptr<vBaseClass*> foo1(new DerviedClass1);
但是 new 给出了类型说明符的错误,但是因为它没有它就可以工作,所以我认为它没什么。 使用 move(foo1) 我得到一个错误 no move for instance of overload function match 并编译一大堆其他错误,例如
unique_ptr<vBaseClass*> champ1 = move(foo1);
error C3867: 'Controller::foo1': 函数调用缺少参数列表;使用 '&Controller::foo1' 创建指向成员的指针 错误 C2780:“_OutTy *std::move(_InIt,_InIt,_OutTy (&)[_OutSize])”:需要 3 个参数 - 提供 1 个
顺便说一句,所有这些都在我的 Controller.h 文件中完成。 我迫切需要指导。我不知道我在做什么是否有必要,我是否需要为此使用 vector ?我怎么开始呢?有更好的方法吗?我什至如何让用户告诉程序要使用哪个对象?对于数组,它将为 foo1 输入 0 或为 foo2 输入 1 但对于 vector ?有没有更好的办法?
我的实际代码
#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.cpp 中声明了它,我仍然不确定如何充分利用它?我真的很想把它作为一个成员变量/实例变量。
正在尝试这样做。在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);
}
上面的代码现在似乎可以工作,但我没有看到任何直接的好处。
最佳答案
说明
你有一个 *
太多了:
unique_ptr<vBaseClass> foo1(new DerivedClass1);
应该通过分配一个新的 DerivedClass1
来解决这个问题具有动态存储持续时间并将指向它的指针存储在 foo1
中.
作为提醒,请大声朗读类型:foo1
类型为“指向 vBaseClass
的唯一指针”。
对于评论中的人群
下图展示了原始指针和唯一指针在用法上的区别:
{
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++ 在解析之前执行文本替换,因此实际的解析器甚至不知道代码来自何处!
业力示范
代码:
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
关于c++ - 需要指导 : Vectors of unique_ptr to dervied classes from an abstract base class,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23498160/