我正在尝试做一些我认为很简单的事情:使用指针链调用调用函数的函数(从继承的类)。有没有更好的方法来完成这个?此外,本着 C++11
的精神,我将如何在此示例中合并智能指针?此示例使应用程序崩溃:
下面是示例代码,如果看起来有点傻,请见谅:
实际输出(崩溃!):
almost there...
期望的输出:
almost there...
hello from function1
f1.h:
#ifndef FUNCTION_1_H
#define FUNCTION_1_H
//f1.h (header file)
#include <iostream>
struct f1{
int _a;
f1() {}
void function1();
};
#endif
f2.h:
#ifndef FUNCTION_2_H
#define FUNCTION_2_H
//f2.h (header file)
#include "f1.h"
struct f2 : public f1{
int _b;
f1* f1_ptr;
f2() :f1(){}
void function2();
};
#endif
f3.h:
#ifndef FUNCTION_3_H
#define FUNCTION_3_H
#include "f2.h"
struct f3 :public f2{
int _c;
f2* f2_ptr;
f3() : f2(){}
void function3();
};
#endif
CPPs:
f3.cpp:
#include "f3.h"
void f3::function3(){
//do stuff...
//e.g. calculate an int Var3
f2_ptr->function2(/*pass Var3 as argument*/);
}
f2.cpp:
#include "f2.h"
void f2::function2(/*receive Var3*/){
//do stuff with Var3
//e.g. maybe use Var3 to calculate an int Var2
std::cout << "almost there..." << std::endl;
f1_ptr->function1(/*pass Var2 as argument*/);
}
f1.cpp:
#include "f1.h"
void f1::function1(/*receive Var2*/){
//take Var2 and use elsewhere
//or continue linking to other functions
std::cout << "hello from function1" << std::endl;
}
main.cpp :
int main(){
f3* ptr3 = new f3;
ptr3->function3();
//delete ptr3;
std::cin.get();
return 0;
}
最佳答案
问题是在上层类中,指针f2*
和 f1*
没有初始化,所以当你做 f2_ptr->function2()
,您正在尝试通过未初始化的指针访问成员函数,这会导致 UB(未定义行为)。您的代码基本上是这样做的:
#include <iostream>
using namespace std;
struct Base
{
void f(){cout << "In f" << endl;}
};
struct Derived
{
Base* ptr;
};
int main()
{
Derived* foo;
foo->ptr->f(); //cannot use foo->ptr, it is not initialized
}
所以你必须确保在 f3
的构造函数中你初始化 f2_ptr
等等。关于智能指针,可以用std::unique_ptr
或 std::shared_ptr
, 语法为 std::unique_ptr<Foo> pointer( new Foo )
(对于 std::shared
也是如此)。强烈推荐使用它们,例如,你必须初始化它们(如果你使用了智能指针就不会出现这个问题)
这里有一个如何写f3.cpp
的提示:
#include "f3.h"
// define the constructor here (and just declare it in the header `f3.h`)
f3::f3() : f2()
{
auto f2_ptr = std::make_shared<f2>();
// and all our nightmares are over, f2_ptr is now a valid pointer
// which will automatically release the allocated memory
// when the reference count is zero
}
void f3::function3()
{
//do stuff...
//e.g. calculate an int Var3
f2_ptr->function2(/*pass Var3 as argument*/);
}
自从我开始这个以来,这里有一个完整的 C++11
带有链接并使用智能指针的示例(它使用类内初始化),它有效并且基本上等同于你的:
#include <iostream>
#include <memory>
using namespace std;
struct Base
{
void f_base()
{
cout << "In f_base" << endl;
}
};
struct Derived
{
void f_derived()
{
cout << "In f_derived" << endl;
}
std::shared_ptr<Base> ptrBase = make_shared<Base>();
};
struct DerivedDerived
{
std::shared_ptr<Derived> ptrDerived = make_shared<Derived>();
};
int main()
{
DerivedDerived *foo = new DerivedDerived;
foo->ptrDerived->ptrBase->f_base(); // OK now
}
PS:这可能有助于您了解发生了什么 When does invoking a member function on a null instance result in undefined behavior?
关于c++ - 使用简单指针链接函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25194648/