我有两个课程A
和B
,其中课程B
看起来像
B.h
class B
{
public:
B();
virtual ~B();
void eval(int a, int b);
private:
A* APointer;
};
相应地我有
B.cpp
B::B():APointer(NULL){}
B::~B(){}
void B::eval(int a, int b)
{
if a == b
{
APointer->run(); // run() is a public method defined in class A
}
}
然后A类就像:
A.h
#include "LuaBridge.h"
extern "C" {
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
}
using namespace luabridge;
class LuaParser
{
public:
LuaParser(lua_State* L);
virtual ~LuaParser();
void run();
private:
LuaRef mRun;
LuaRef mStop;
lua_State* mL;
};
并且
A.cpp
LuaParser::LuaParser(lua_State* L) :mRun(L),mStop(L),mL(L) {}
LuaParser::~LuaParser(){}
void LuaParser::run(){
std::cout<<"This project runs!"<<std::endl;
}
系统很复杂,实际上我在类C
成员函数中调用了这个eval函数。在该类中,我通过B* BPointer
定义了一个私有成员BPointer,在构造函数中我做了C(B* BPointer = NULL)
,然后我只在类C成员函数中使用BPointer->eval(a,b)
。
在我的main
代码中,我在类B中定义一个指针,如B* BPointer
,我使用此指针通过
B::eval
BPointer -> eval(a, b);
然而,当我在visual studio中一步一步地运行它时,在命令行APointer->run();
我注意到this
指针就像:
Value: 0xcdcdcdcd{APointer=???}
当我尝试运行此命令时,出现错误:
Access violation reading location 0xCDCDCDD1.
嗯......我不知道如何解决这个问题,我想知道的是:
整个想法(即使用私有对象在此类方法中调用另一个类的函数)是否可行?
如果这个想法可行,那么我应该如何修改我的代码?
任何建议或想法都非常受欢迎!
答案 0 :(得分:0)
你必须在类B的构造函数中用一些真实对象初始化APointer
数据成员。它应该如下所示:
B::B()
{
this->APointer = new A();
}
B::~B()
{
delete this->APointer;
this->APointer = NULL;
}
...
...
int main()
{
B* BPointer = new B();
int x = 5;
int y = 5;
BPointer->eval(x, y);
}
在上面提到的代码中,APointer
被初始化为NULL
。我认为执行B::eval()
时会导致一些未定义的行为。
如果您还可以发布A类代码,那将是件好事。
答案 1 :(得分:0)
0xcdcdcdcd
是已分配但尚未初始化的内存的状态。您是否以适当的方式实例化了BPointer
?例如
BPointer = new B();
除此之外,您的APointer为NULL,因此您无法调用任何方法,如
APointer->run();
在构造A类型的对象并将其分配给APointer之前。
答案 2 :(得分:0)
是整个想法(即使用私有对象来调用函数) 这个方法中的另一个类可行吗?
是的,这很常见。
如果这个想法可行,那么我该如何修改我的代码?
您需要了解对象和指针之间的区别。指针是内存区域的地址,甚至可以是未分配的。
这里有两个没有指向任何已分配内存的指针,因此没有可以调用其方法的对象。
BPointer
是单元化的,它包含随机存储区域的地址(或调试版本中的幻数0xcdcdcdcd
),它可能只包含属于或不属于您的任何内容。取消引用它是undefined behavior。为避免这种情况,您应该创建B
对象并将其指向BPointer
:
B *BPointer = new B;
使用完BPointer
之后,你应该释放内存并通过调用
B
的析构函数
delete BPointer;
APointer
使用NULL
指针初始化,这意味着它不指向任何内存区域。取消引用NULL
也是未定义的行为。与BPointer
类似,它应该使用有效的对象指针初始化并稍后释放:
B::B() : APointer(new A(/* lua state pointer */ NULL)) {}
B::~B() { delete APointer; }
如果你不一定需要指针,我建议使用B
的堆栈分配,并将A
存储为普通成员(不是指针)。这样您就不需要为指针初始化和删除而烦恼了。
B.h
class B
{
public:
B();
void eval(int a, int b);
private:
A AObject;
};
B.cpp
B::B() : AObject(/* lua state pointer */ NULL) {}
void B::eval(int a, int b)
{
if (a == b)
{
AObject.run();
}
}
的main.cpp
// ...
B b;
b.eval()
// ...