【问题标题】:How can I call a method of derivitive class within base's class constructor using a pointer to function?如何使用指向函数的指针在基类构造函数中调用派生类的方法?
【发布时间】:2021-09-09 01:05:37
【问题描述】:

免责声明:我是一名 C 开发人员,这是我第一次在 C++ 中尝试这样的事情。我对该语言的经验为零。

我有一个类 Bob,它有一个指向函数 myFunction 作为私有成员的指针。

我想继承类Bob,并使用基类构造函数将派生类的方法传递给指针函数。

这是我的代码:

#include <iostream>

using FuncHandler = void (*)(int x);

class Bob
{
    protected:
    Bob(FuncHandler x)
    {
        myFunction = x;

        // When I call the function here
        // I get garbage...
        // x value is = 932452288
        myFunction(10);
    }

    private:
    FuncHandler myFunction;
};

class Alice : public Bob
{
    public:
    Alice() : Bob(reinterpret_cast<FuncHandler>(&Alice::foo))
    {
        
    }
    void foo(int x);
};

void Alice::foo(int x)
{
    std::cout << "x value is = " << x << "\n";
}

int main(void)
{
    Alice obj1;
    return 0;
}

问题是我做错了什么,输出垃圾?

【问题讨论】:

  • 让它static void foo(int x);
  • @Eljay 你是对的!谢谢 !!!你能发布一个答案让我接受吗?

标签: c++ inheritance constructor


【解决方案1】:

using FuncHandler = void (*)(int x); 是函数指针的方便名称。

Alice 的void foo(int x); 不是一个函数,它是一个成员函数。成员函数与独立函数不同。

幸运的是,在这种特殊情况下,代码不需要访问作为 Alice 的成员函数的函数,它可以使用与函数指针兼容的静态类函数。假设签名匹配,在这种情况下它们匹配。

void foo(int x); 更改为static void foo(int x);

然后把Alice() : Bob(reinterpret_cast&lt;FuncHandler&gt;(&amp;Alice::foo))改成Alice() : Bob(&amp;Alice::foo),代码就设置好了。

注意:如果foo 函数需要访问 Alice 的实例状态,则会出现问题,因为在代码中的那个构造点,Alice 对象还没有被构造。

【讨论】:

    【解决方案2】:

    我发现您的方法存在两个主要问题。

    首先,基类在派生类之前构造。在基类构造函数内部,派生类还不存在,因此调用派生类的非静态成员函数是未定义的行为。

    其次,您的功能转换无效。它在某种意义上有效,但转换后的值不能安全使用。每当您觉得需要使用reinterpret_cast 时,不要;请改用static_castdynamic_cast。虽然reinterpret_cast 有一些有效的用途,但初学者往往会在不好的地方使用它。静态和动态强制转换足够强大,可以满足大多数需求,但当您尝试做一些不适当的事情(例如转换)时,它们又足够弱以至于失败。 (指向成员函数的指针与指向函数的指针是不同的野兽。虽然编译器可能允许将一个转换为另一个,但通过转换后的值调用函数是不安全的。 )

    您可能应该回到绘图板上。至少,如果成员函数不使用this 指针,请记住标记static。您可能会让您的 C 背景模糊您的 C++ 思维。 (当然,这是猜测,因为我不知道你的real problem。)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多