我正在尝试做一些我认为很简单的事情:调用使用指针链调用函数(来自继承类)的函数。有没有更好的方法来实现这一目标?另外,本着C++11
的精神,我如何在这个例子中加入智能指针?此示例崩溃了应用程序:
这是示例代码,如果看起来有点傻话,请道歉:
almost there...
almost there...
hello from function1
#ifndef FUNCTION_1_H
#define FUNCTION_1_H
//f1.h (header file)
#include <iostream>
struct f1{
int _a;
f1() {}
void function1();
};
#endif
#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
#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
#include "f3.h"
void f3::function3(){
//do stuff...
//e.g. calculate an int Var3
f2_ptr->function2(/*pass Var3 as argument*/);
}
#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*/);
}
#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;
}
int main(){
f3* ptr3 = new f3;
ptr3->function3();
//delete ptr3;
std::cin.get();
return 0;
}
答案 0 :(得分:1)
问题是在上层类中,指针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?