c++ - 使用简单指针链接函数

标签 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

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_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?

关于c++ - 使用简单指针链接函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25194648/

相关文章:

c++ - 标记/编码指针

c++ - 'round' 不是 'std' 的成员

c - C中主下标值错误

objective-c - 与 Objective C 交换对象

c++ - 使用 C 程序启用禁用键

c++ - 如何使用 C++11 创建高效的闭包?

c++ - 我必须在这里使用指针吗?

c++ - 在 C++ 中复制仅具有基类指针的派生类

c++ - 在没有显式调用的情况下强制在子方法之前执行父方法

c++ - 自动协变类推导