C++;语法错误 我试图在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>
ScreenManager.cppC++;语法错误 我试图在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>,c++,opengl,vector,syntax,C++,Opengl,Vector,Syntax,ScreenManager.cpp std::vector<virtualGameScreen*> gameScreen; void ScreenManager::Initialize(void) { MainMenu menu = MainMenu(); AddScreen(menu); } void ScreenManager::AddScreen(virtualGameScreen gameScreenToAdd) { gameScreenToAd
std::vector<virtualGameScreen*> gameScreen;
void ScreenManager::Initialize(void)
{
MainMenu menu = MainMenu();
AddScreen(menu);
}
void ScreenManager::AddScreen(virtualGameScreen gameScreenToAdd)
{
gameScreenToAdd.LoadContent();
gameScreen.push_back(gameScreenToAdd);
}
std::vector gameScreen;
void屏幕管理器::初始化(void)
{
MainMenu=MainMenu();
添加屏幕(菜单);
}
无效屏幕管理器::添加屏幕(virtualGameScreen游戏屏幕添加)
{
gameScreenToAdd.LoadContent();
游戏屏幕。向后推(游戏屏幕添加);
}
所以,我遇到了点麻烦,有什么建议可以帮我解决这个问题吗
编辑如果我更改游戏屏幕,则游戏运行。推回游戏屏幕。推回(新主菜单());但是这并不是我想要的函数在C++11之前的代码中工作的方式,您可能会遇到如下情况:
std::vector<virtualGameScreen*> gameScreen;
void ScreenManager::Initialize(void)
{
AddScreen(new MainMenu);
}
void ScreenManager::AddScreen(virtualGameScreen *gameScreenToAdd)
{
gameScreenToAdd->LoadContent();
gameScreen.push_back(gameScreenToAdd);
}
std::vector<std::unique_ptr<virtualGameScreen>> gameScreen;
std::vector gameScreen;
void屏幕管理器::初始化(void)
{
添加屏幕(新主菜单);
}
无效屏幕管理器::添加屏幕(VirtualGamesScreen*游戏屏幕添加)
{
游戏屏幕添加->加载内容();
游戏屏幕。向后推(游戏屏幕添加);
}
但是你必须有办法确保对象被删除
使用C++11,您可能希望自动管理内存:
std::vector<std::unique_ptr<virtualGameScreen>> gameScreen;
void ScreenManager::Initialize(void)
{
AddScreen(std::unique_ptr<MainMenu>(new MainMenu));
}
void ScreenManager::AddScreen(std::unique_ptr<virtualGameScreen> gameScreenToAdd)
{
gameScreenToAdd->LoadContent();
gameScreen.emplace_back(std::move(gameScreenToAdd));
}
std::vector gameScreen;
void屏幕管理器::初始化(void)
{
AddScreen(标准::unique_ptr(新主菜单));
}
void ScreenManager::AddScreen(std::unique_ptr gamescreen to add)
{
游戏屏幕添加->加载内容();
游戏屏幕。向后放置(标准::移动(游戏屏幕添加));
}
在C++11之前的代码中,您可能会遇到如下情况:
std::vector<virtualGameScreen*> gameScreen;
void ScreenManager::Initialize(void)
{
AddScreen(new MainMenu);
}
void ScreenManager::AddScreen(virtualGameScreen *gameScreenToAdd)
{
gameScreenToAdd->LoadContent();
gameScreen.push_back(gameScreenToAdd);
}
std::vector<std::unique_ptr<virtualGameScreen>> gameScreen;
std::vector gameScreen;
void屏幕管理器::初始化(void)
{
添加屏幕(新主菜单);
}
无效屏幕管理器::添加屏幕(VirtualGamesScreen*游戏屏幕添加)
{
游戏屏幕添加->加载内容();
游戏屏幕。向后推(游戏屏幕添加);
}
但是你必须有办法确保对象被删除
使用C++11,您可能希望自动管理内存:
std::vector<std::unique_ptr<virtualGameScreen>> gameScreen;
void ScreenManager::Initialize(void)
{
AddScreen(std::unique_ptr<MainMenu>(new MainMenu));
}
void ScreenManager::AddScreen(std::unique_ptr<virtualGameScreen> gameScreenToAdd)
{
gameScreenToAdd->LoadContent();
gameScreen.emplace_back(std::move(gameScreenToAdd));
}
std::vector gameScreen;
void屏幕管理器::初始化(void)
{
AddScreen(标准::unique_ptr(新主菜单));
}
void ScreenManager::AddScreen(std::unique_ptr gamescreen to add)
{
游戏屏幕添加->加载内容();
游戏屏幕。向后放置(标准::移动(游戏屏幕添加));
}
这是因为您没有提供指向向量(游戏屏幕)的指针,而关于代码的另一个问题是:参数将生成一个临时对象,如果只是输入它的地址,应用程序可能会崩溃。这是因为您没有提供指向向量(游戏屏幕)的指针,关于代码的另一个问题是:paramater将生成一个temp对象,如果只输入它的地址,应用程序可能会崩溃。因此,编译器做的第一件事是告诉您问题发生在哪里:
1>screenmanager.cpp(26)
它还主要告诉您问题是什么:
Reason: cannot convert from 'virtualGameScreen' to 'virtualGameScreen *'
因此-代码中的某些内容提供了一个“VirtualGamesScreen”对象实例,在该实例中它需要一个指针(由*
表示)。在26号线。错误的其他部分表明这是一个向后推的调用。让我们看看第26行:
gameScreen.push_back(gameScreenToAdd);
是的-您正在调用push_back,并将其传递给添加GameScreen
,类型为virtualGameScreen
。push_back
调用来自以下向量:
std::vector<virtualGameScreen*> gameScreen;
因为gameScreenToAdd
是一个临时函数变量-当您调用AddScreen
时,原始变量会在函数调用的生命周期内复制到一个新的临时virtualgamesscreen中。这意味着当程序离开AddScreen时,您按下地址的屏幕将不再存在(内存仍然存在,但已被释放,计算机现在将出于其他原因继续使用它)
您需要做的是更改AddScreen以获取指针
void ScreenManager::AddScreen(virtualGameScreen* gameScreenToAdd)
{
gameScreenToAdd.LoadContent();
gameScreen.push_back(gameScreenToAdd);
}
不幸的是,这会使您的代码面临另一个问题
void ScreenManager::Initialize(void)
{
MainMenu menu = MainMenu();
AddScreen(menu);
}
此函数创建一个临时的本地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::UnQuyQPTR还是STD::SyrdYPPTR
----编辑----
看到我写这篇文章时你所做的编辑,你想做的事情就更清楚了。你可能想要的是更像这样的东西:
std::vector<virtualGameScreen*> gameScreen;
void ScreenManager::Initialize(void)
{
AddScreen(new MainMenu);
}
void ScreenManager::AddScreen(virtualGameScreen *gameScreenToAdd)
{
gameScreenToAdd->LoadContent();
gameScreen.push_back(gameScreenToAdd);
}
std::vector<std::unique_ptr<virtualGameScreen>> gameScreen;
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;
}
现在您根本不需要m_菜单,只需使用“new Main menu()”调用AddScreen,指针就会添加到向量中,这样当向量超出范围时,就会进行适当的清理
Menu* menu = new MainMenu();
AddScreen(menu);
或
从理论上讲,您真正应该做的是确保分配直接进入一个唯一的\u ptr对象,这样就不会有窗口让它泄漏,但是教授std::unique\u ptr的使用超出了这个答案的范围,等等。因此,编译器做的第一件事就是告诉您问题发生在哪里:
1>screenmanager.cpp(26)
它还主要告诉您问题是什么:
Reason: cannot convert from 'virtualGameScreen' to 'virtualGameScreen *'
因此-代码中的某些内容提供了一个“VirtualGamesScreen”对象实例,在该实例中它需要一个指针(由*
表示)。在26号线。错误的其他部分表明这是一个向后推的调用。让我们看看第26行:
gameScreen.push_back(gameScreenToAdd);
是的,你叫push_back,你是passi