gpt4 book ai didi

c++ - 函数模板 : Access Child Class' Overloaded Function In Base Class

转载 作者:行者123 更新时间:2023-11-30 04:15:21 25 4
gpt4 key购买 nike

我有一个基类 First和派生类 Second .在基类中有一个成员函数 create和一个虚函数 run .在 Second 的构造函数中我想调用函数 First::create ,它需要访问其子类的实现'run()功能。自 First 以来,一位同事建议使用函数模板无法明确知道它的子类。听起来怪怪的?这是一些代码:

First.h

#pragma once
#include <boost/thread/thread.hpp>
#include <boost/chrono/chrono.hpp>

class First
{
public:
First();
~First();

virtual void run() = 0;
boost::thread* m_Thread;
void create();

template< class ChildClass >
void create()
{
First::m_Thread = new boost::thread(
boost::bind( &ChildClass::run , this ) );
}
};

First.cpp

#include "First.h"

First::First() {}
First::~First() {}

第二.h

#pragma once
#include "first.h"

class Second : public First
{
public:
Second();
~Second();

void run();
};

第二个.cpp

#include "Second.h"
Second::Second()
{
First::create<Second>();
}

void Second::run()
{
doSomething();
}

我在 First::create<Second>(); 处遇到错误说错误:不允许类型名称。那么这个错误的原因是什么?我想我还没有完全了解模板的全部机制,但我对这个主题还很陌生。

最佳答案

虽然您可以按照 Kerrek SB 和 Arne Mertz 的“建议”使用 CRTP,但这里有一个使用成员函数模板的解决方案:

class First
{
public:
First();
~First();

virtual void run() = 0;
boost::thread* m_Thread;

// vvvvvvvvvvv this declares a non-template member function `create`
void create(); // (better remove it)

// vvvvvvvvvv this declares a member function template `create`
template< class ChildClass >
void create();
};

对于模板,您应该在头文件中提供定义,因为定义必须在需要它的每个 TU 中可用(而不仅仅是在一个 TU 中)。

最简单的方法是在类本身中提供成员函数模板或类模板成员的定义:

class First
{
public:
/* ... */

template< class ChildClass >
void create()
{
// AFAIK, the `bind` is not required
First::m_Thread = new boost::thread(&ChildClass::run,
static_cast<ChildClass*>(this));
}
};

现在,如果你想在Second中调用这个成员函数模板类,您必须显式提供模板参数:

void Second::any_function()
{
create<Second>();
}

您的代码的一些其他(可能)问题:

  • 您没有虚拟 dtor,因此删除指向基类子对象的指针将调用 UB。
  • 需要有一个沮丧,因为&ChildClass::run类型为 void (Second::*)() .
  • createSecond 的构造函数中被调用,这将调用 Second::run (或您提供的任何模板参数),类中该函数的最终覆盖 Second 。如果您在派生自 Second 的类中覆盖该函数, 将不会在 Second 的构造函数中调用该覆盖.
  • 您的 First 的负责人应该 detachjoin提升线程,否则std::terminate如果在调用 dtor 时线程仍在运行,将被调用。
  • run在这个例子中不必虚拟,完全相同的代码可以在没有 run 的情况下工作是虚拟的,甚至在 First 中声明.

关于c++ - 函数模板 : Access Child Class' Overloaded Function In Base Class,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18377236/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com