1

I'm trying to streamline my code and make it work better and easier:

This means diving into vectors and unique_ptr, about which I've read so many good things. However, they are entirely new to me. I have read a few pages on both, but its a lot to wrap my head around.

What I'm currently doing is creating objects of abstract class the traditional way:

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

But since I have 3 - and quite possibly will have lots more - I want to make it easier to switch between them because I'm going to be comparing any combination of the objects each program run.

Currently, to switch, I just rename the DerviedClass for which I want to instantiate an object so I don't have to go in renaming each foo1 with foo3, etc..

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

But ultimately I want the user to tell the program which two objects to compare. So a good starting point seems to make this an array of the VirtualBaseClass, but from research it seems like its pain to have to delete the arrays so people recommend using smart pointers and vectors.

So I tried to use both. For unique pointers I do

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

However, from what I read I should be doing

unique_ptr<vBaseClass*> foo1(new DerviedClass1);

but new gives error of type specfier but since it works without it I think nothing of it. With move(foo1) I get an error no move for instance of overload function match and on compile a whole host of other errors such as

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

error C3867: 'Controller::foo1': function call missing argument list; use '&Controller::foo1' to create a pointer to member error C2780: '_OutTy *std::move(_InIt,_InIt,_OutTy (&)[_OutSize])' : expects 3 arguments - 1 provided

All this is being done in my Controller.h file btw. I'm in desperate need of guidances. I don't know if what I'm doing is even neccsary, do I need to use vectors with this? How would I even begin too? Is there a better way of doing this? How do I even get the user to tell the program which object to use? With arrays it would be enter 0 for foo1 or enter 1 for foo2 but with vectors? Is there a better way?

My acutal code

#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 
};

Wow so apparently you can't use the "new" in a header file only in the cpp file. However I'm still not sure how to make good use of it now that I have it declared in the controller.cpp? I really wanted it as a member variable/instance variable.

Trying to do this. in controller.h

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

and in the .cpp to define them

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);

}

The above code now seems to work but I'm failing to see any direct benefits.

Nonlin
  • 550
  • 1
  • 6
  • 18

2 Answers2

1

Explanation

You got a * to much:

unique_ptr<vBaseClass> foo1(new DerivedClass1);

should do the trick by allocating a new DerivedClass1 with dynamic storage duration and storing the pointer to it in foo1.

As a reminder, just read the type aloud: foo1has type "unique pointer to vBaseClass".

For the crowd in the comments

The following shows the difference in usage between a raw pointer and a unique pointer:

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

There is no further difference. Any further problem you have is related to a different problem that is hard to pinpoint without further information.

Also, unique_ptr<Champion*> riven(Riven); is a function declaration for a function by the name of riven returning a unique_ptr<Champion*> and taking a single argument of type Riven. The reason this does not error is because it does not do what you think it does at all.

Finally, there is absolutely nothing that makes headers anything special. In fact, C++ performs text substitution before parsing, so that the actual parser does not even know anything about where the code came from anymore!

Karmic Demonstration

Code:

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";
}

Result:

karma, karma

Proof

danielschemmel
  • 10,885
  • 1
  • 36
  • 58
  • With or without the * it won't work. new always give the same error. – Nonlin May 06 '14 at 15:28
  • Should the dereference notation (*) be placed before identifier `foo1`, e.g.: `unique_ptr *foo1(new DerivedClass1);` – Thomas May 06 '14 at 15:31
  • @thomas seems to make no difference where or how many * I put. – Nonlin May 06 '14 at 15:58
  • So apparently you can't use the "new" in a header file only in the cpp file. – Nonlin May 06 '14 at 16:15
  • @Nonlin You can use `new` in headers. – danielschemmel May 06 '14 at 16:48
  • @Nonlin As I said before, you must have another mistake somewhere. One that is not detectable without more information. Create a [MCVE](http://stackoverflow.com/help/mcve) if you need further help. – danielschemmel May 06 '14 at 17:05
  • I got it to work using shared_ptr, just not sure if its the best way to be done. At least now I can access shared_ptr from a controller object. As for new not working idk. Now I just need to figure out how to make the user pick which shared_ptr is going to get assigned. – Nonlin May 06 '14 at 17:08
0

unique_ptr<Champion> yi(new MasterYi);// doesn't work new error looks like a function declaration to the compiler, and new isn't valid in that context.

unique_ptr<Champion*> riven(Riven); //works with or without * also looks like a function declaration and is valid with or without the *.

unique_ptr<Champion*> champ1 = move(riven)//error with move You can't move a function into a unique_ptr.

I'm having a really hard time understanding your question but maybe you mean something like this:

unique_ptr<Champion> yi = new MasterYi;
unique_ptr<Champion> riven = new Riven;
std::vector<std::unique_ptr<Champion> > pChampions = { new Skarner };
Mark B
  • 95,107
  • 10
  • 109
  • 188
  • shouldn't riven be an object now that I did unique_ptr riven(Riven); or am I misinterpreting unique_ptr. How do I make it not look like a function deceleration? – Nonlin May 06 '14 at 16:04
  • So apparently you can't use the "new" in a header file only in the cpp file. Not sure if that was what you were getting at. – Nonlin May 06 '14 at 16:15