另一个 class 的 c++ 私有对象:初始化并使用它来调用 class 中的函数
c++ private object of another class: initialization and use it to call a function in that class
我有两个 classes A
和 B
,其中 class 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
}
}
那么 class 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;
}
系统很复杂,实际上我在class C
成员函数中调用了这个eval函数。在那个 class 中,我通过 B* BPointer
定义了一个私有成员 BPointer,在构造函数中我做了 C(B* BPointer = NULL)
,然后我在 class C 成员函数中简单地使用了 BPointer->eval(a,b)
。
在我的 main
代码中,我在 class B 中定义了一个指针,如 B* BPointer
我使用这个指针通过 [=31= 调用方法 B::eval
]
BPointer -> eval(a, b);
然而,当我 运行 它在 visual studio 中一步一步地执行时,在命令行 APointer->run();
我注意到 this
指针是这样的:
Value: 0xcdcdcdcd{APointer=???}
当我尝试 运行 这个命令时,我得到了一个错误:
Access violation reading location 0xCDCDCDD1.
嗯...我不知道如何解决这个问题,我想知道的是:
整个想法(即在这个class的方法中使用私有对象调用另一个class的函数)是否可行?
如果这个想法可行,那我应该如何修改我的代码?
我们非常欢迎任何建议或想法!
您必须在 class 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()
被执行时,它会导致一些未定义的行为。
如果你也能post class A的代码就更好了
0xcdcdcdcd
是已分配但尚未初始化内存的状态。您是否以适当的方式实例化了 BPointer
?例如
BPointer = new B();
除此之外,您的 APointer 为 NULL,因此您不能调用任何方法,例如
APointer->run();
在构造类型 A 的对象并将其分配给 APointer 之前。
Is the whole idea (i.e. use a private object to call function of
another class in a method of this class) feasible?
是的,这很常见。
If this idea is feasible, then how should I modify my code?
您需要了解对象和指针之间的区别。指针是内存区域的地址,甚至可能未分配。
这里有两个指针不指向任何分配的内存,因此没有对象的方法可以调用。
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()
// ...
我有两个 classes A
和 B
,其中 class 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
}
}
那么 class 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;
}
系统很复杂,实际上我在class C
成员函数中调用了这个eval函数。在那个 class 中,我通过 B* BPointer
定义了一个私有成员 BPointer,在构造函数中我做了 C(B* BPointer = NULL)
,然后我在 class C 成员函数中简单地使用了 BPointer->eval(a,b)
。
在我的 main
代码中,我在 class B 中定义了一个指针,如 B* BPointer
我使用这个指针通过 [=31= 调用方法 B::eval
]
BPointer -> eval(a, b);
然而,当我 运行 它在 visual studio 中一步一步地执行时,在命令行 APointer->run();
我注意到 this
指针是这样的:
Value: 0xcdcdcdcd{APointer=???}
当我尝试 运行 这个命令时,我得到了一个错误:
Access violation reading location 0xCDCDCDD1.
嗯...我不知道如何解决这个问题,我想知道的是:
整个想法(即在这个class的方法中使用私有对象调用另一个class的函数)是否可行?
如果这个想法可行,那我应该如何修改我的代码?
我们非常欢迎任何建议或想法!
您必须在 class 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()
被执行时,它会导致一些未定义的行为。
如果你也能post class A的代码就更好了
0xcdcdcdcd
是已分配但尚未初始化内存的状态。您是否以适当的方式实例化了 BPointer
?例如
BPointer = new B();
除此之外,您的 APointer 为 NULL,因此您不能调用任何方法,例如
APointer->run();
在构造类型 A 的对象并将其分配给 APointer 之前。
Is the whole idea (i.e. use a private object to call function of another class in a method of this class) feasible?
是的,这很常见。
If this idea is feasible, then how should I modify my code?
您需要了解对象和指针之间的区别。指针是内存区域的地址,甚至可能未分配。
这里有两个指针不指向任何分配的内存,因此没有对象的方法可以调用。
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()
// ...