我最近从PHP和LSL等脚本语言返回到C ++,其中一些范围规则让我感到困惑。
说我有一个像这样的Viewer.h:
class Viewer {
public:
Viewer();
~Viewer();
void ping();
void setBgColour(int r, int g, int b, int a);
float bg_r;
float bg_g;
float bg_b;
float bg_a;
};
和Viewer.C一样:
#include "Globals.h"
#include "Viewer.h"
Viewer::Viewer() {}
Viewer::~Viewer() {}
void Viewer::ping() {
cout << "Viewer::ping() " << endl;
}
void Viewer::setBgColour(int r, int g, int b, int a) {
bg_r = r/255.0;
bg_g = g/255.0;
bg_b = b/255.0;
bg_a = a/255.0;
}
我已在Global中声明了我的查看器类的实例。{h | C}为&#39; extern&#39;为了能够从其他文件访问全局查看器实例。
现在考虑一下,当我在例如UI.C中调用全局查看器实例方法时:
viewer->ping();
viewer->setBgColour(123, 45, 56, 255);
viewer-&gt; ping()工作正常,但是viewer-&gt; setBgColour()在尝试访问实例变量bg_r,bg_g,bg_b和bg_a时给了我一个分段错误。
我的理解是我没有访问正确的查看器实例。
viewer-&gt; ping()并不关心,因为无论实际调用它的实例如何,它都会将文本回显给cout。但是setBgColour()需要访问正确的内存位置,因此当它无法找到它们时会出现段错误。
这让我感到困惑,因为我/我的印象是宣称我的观众实例为“外部”。会“只是工作”。傻我。我已经尝试将变量声明为&#39;静态&#39;但这让我更加困惑。
答案 0 :(得分:1)
如果在发布行之前代码中的viewer
没有完成,那么你有未初始化的指针Viewer* viewer
。取消引用此类指针会导致分段错误。如果要修复它,则应将创建的对象的地址分配给指针。
可能:
(在main
开头)
viewer = new Viewer();
// some code here
delete viewer;
或者为其分配现有全局变量的地址。
答案 1 :(得分:0)
不要使用全局实例,而应考虑使用单例。实际上没有必要在堆上分配您的查看器。
e.g。
#include <iostream>
using std::cout;
class Viewer
{
float bg_r;
float bg_g;
float bg_b;
float bg_a;
Viewer(Viewer const&) = delete;
Viewer& operator=(Viewer const&) = delete;
public:
Viewer()
: bg_r(0.0), bg_g(0.0), bg_b(0.0), bg_a(0.0)
{}
void ping();
void setBgColour(int r, int g, int b, int a);
};
void Viewer::ping()
{
cout << "Viewer::ping()\n";
}
void Viewer::setBgColour(int r, int g, int b, int a)
{
bg_r = r/255.0;
bg_g = g/255.0;
bg_b = b/255.0;
bg_a = a/255.0;
}
Viewer& GetViewer()
{
static Viewer v;
return v;
}
int main()
{
GetViewer().ping();
GetViewer().setBgColour(1,2,3,4);
}