我正在尝试使用C ++创建一种屏幕管理器,但出现错误。在下面的代码中,我收到了
1>screenmanager.cpp(26): error C2664: 'void std::vector<_Ty>::push_back(_Ty &&)' : cannot convert parameter 1 from 'virtualGameScreen' to 'virtualGameScreen *&&'
1> with
1> [
1> _Ty=virtualGameScreen *
1> ]
1> Reason: cannot convert from 'virtualGameScreen' to 'virtualGameScreen *'
1> No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
1>
gameScreen.push_back(gameScreenToAdd)发生错误;使用gameScreenToAdd添加引用运算符时出现访问冲突错误。
屏幕管理器
void AddScreen(virtualGameScreen);
void RemoveScreen(virtualGameScreen);
屏幕管理器
std::vector<virtualGameScreen*> gameScreen;
void ScreenManager::Initialize(void)
{
MainMenu menu = MainMenu();
AddScreen(menu);
}
void ScreenManager::AddScreen(virtualGameScreen gameScreenToAdd)
{
gameScreenToAdd.LoadContent();
gameScreen.push_back(gameScreenToAdd);
}
所以,我碰壁了,关于如何解决此问题的任何建议?
如果将gameScreen.push_back更改为gameScreen.push_back(new MainMenu()),则编辑游戏运行 我不是真的希望功能起作用
因此,编译器所做的第一件事就是告诉您问题出在哪里:
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实例的生命周期内存储“菜单”。
选项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 ++容器为您管理指针的生命周期,即std :: 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 :: vector这样的容器
#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了,您只需使用“ new MainMenu()”调用AddScreen,指针就会添加到向量中,以便当向量超出范围时,将进行适当的清理。
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等。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句