,编译器做的第一件事就是告诉你在哪里出现问题:
1>screenmanager.cpp(26)
它还告诉你的问题主要是什么:
Reason: cannot convert from 'virtualGameScreen' to 'virtualGameScreen *'
这样的 - 我在你的代码正在提供一个“virtualGameScreen”对象实例,该实例正在等待一个指针(由*
表示)。它在第26行。错误的其他部分表明这是对push_back的调用。让我们看看第26行:
gameScreen.push_back(gameScreenToAdd);
是的 - 你打电话的push_back,而你通过它gameScreenToAdd
,这是virtualGameScreen
类型。该push_back
电话是从这个载体:
std::vector<virtualGameScreen*> gameScreen;
你的矢量预计指针,所以预计的push_back载体。
但是:你不能做到这一点:
gameScreen.push_back(&gameScreenToAdd);
因为gameScreenToAdd
是一个临时的函数的变量 - 当你调用AddScreen
,原来的变量被复制到一个新的,临时virtualGameScreen为的寿命函数调用。这意味着当程序离开AddScreen时,您推送的地址将不再存在的屏幕(内存仍然存在,但它已被释放,并且计算机现在将继续使用它以用于其他原因)。
你需要做的就是改变AddScreen来取指针。
void ScreenManager::AddScreen(virtualGameScreen* gameScreenToAdd)
{
gameScreenToAdd.LoadContent();
gameScreen.push_back(gameScreenToAdd);
}
不幸的是,这会让您打开代码的另一个问题。
void ScreenManager::Initialize(void)
{
MainMenu menu = MainMenu();
AddScreen(menu);
}
该函数创建一个临时的本地MainMenu对象,并且其生命周期为Initialize。然后它创建第二个临时MainMenu并将其复制到菜单。
如果你写
AddScreen(&menu);
它会工作,但它会一个临时的实例的地址传递给AddScreen。
只要程序流程离开“Initialize()”函数,您的值就会消失。
它看起来像你可能有一些像Java或C#之类的东西的经验,并试图将以前的知识应用于C++。
你需要的是一个成员变量来存储ScreenManager实例生命期的“Menu”。
选项1:只需使用类成员变量。
class ScreenManager
{
MainMenu m_menu;
public:
ScreenManager()
: m_menu() // initialize menu while we are initializing.
{}
void Initialize()
{
AddScreen(&m_menu);
}
// ...
};
如果你真的想用一个指针,你不妨做到以下几点:
class ScreenManager
{
MainMenu* m_menu;
public:
ScreenManager()
: m_menu(nullptr) // make sure it's null as soon as the object is created
{}
void Initialize()
{
m_menu = new MainMenu();
AddScreen(m_menu);
}
// but now we have to make sure it is released when we go away
~ScreenManager()
{
if (m_menu)
{
delete m_menu;
m_menu = nullptr;
}
}
};
方案3:使用C++容器管理指针的一生为你,无论是标准::的unique_ptr或std :: shared_ptr的
---- ----编辑
看到你,我在写这篇而做出的编辑,这是一个更清晰一点你想要做什么。你可能需要的是更多的东西是这样的:
std::vector<std::unique_ptr<virtualGameScreen>> gameScreen;
考虑以下几点:
现场演示:http://ideone.com/7Th2Uk
#include <iostream>
#include <vector>
class Foo {
const char* m_name;
public:
Foo(const char* name) : m_name(name) { std::cout << "Foo " << m_name << '\n'; }
~Foo() { std::cout << "~Foo " << m_name << '\n'; }
};
int main() {
std::vector<Foo*> foos;
Foo foo("foo");
foos.push_back(new Foo("new"));
return 0;
}
注意,第二FOO永远不会释放。
Foo foo
Foo new
~Foo foo
std::unique_ptr
是一个指针,容器对象,当对象过期,这将删除对象。这使得它适合于喜欢的std ::向量容器使用
#include <iostream>
#include <vector>
#include <memory> // for std::unique_ptr
class Foo {
const char* m_name;
public:
Foo(const char* name) : m_name(name) { std::cout << "Foo " << m_name << '\n'; }
~Foo() { std::cout << "~Foo " << m_name << '\n'; }
};
int main() {
std::vector<std::unique_ptr<Foo>> foos;
Foo foo("foo");
foos.emplace_back(new Foo("new"));
return 0;
}
两个对象都得到清理:
Foo foo
Foo new
~Foo foo
~Foo new
现在你不需要你m_menu可言,你可以简单地调用AddScreen与一个'新的MainMenu()'和指针将被添加到矢量,以便当矢量超出范围时,将发生适当的清理。
Menu* menu = new MainMenu();
AddScreen(menu);
或
AddScreen(new MainMenu());
在理论上是什么你应该做的是确保分配直接进入一个的unique_ptr对象,这样有没有窗口,它得到泄露,但教学使用的std :: unique_ptr超出了这个答案的范围。 http://msdn.microsoft.com/en-us/library/hh279676.aspx,http://www.drdobbs.com/cpp/c11-uniqueptr/240002708等
你已经声明了一个'std :: vector'来存放_pointers_,但是你正试图'push_back()'一个_object_。你需要决定哪一个是你真正想要的。 – Blastfurnace