使用简单指针链接函数

时间:2014-08-08 01:09:03

标签: c++ pointers inheritance

我正在尝试做一些我认为很简单的事情:调用使用指针链调用函数(来自继承类)的函数。有没有更好的方法来实现这一目标?另外,本着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

的CPP:

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;
    }

1 个答案:

答案 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_ptrstd::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?