是否可以让继承函数调用派生重载函数?

问题描述 投票:0回答:1

假设我有3节课:

example.h

class Object {
public:
    Object();

    void pass_self_to_external_class();
};

class ObjectWithExtraMember : public Object {
public:
    ObjectWithExtraMember();

    int extra_member;
};

class ExternalClass {
public:
    ExternalClass();
    
    void do_something_with_object(Object* object);
    void do_something_with_object(ObjectWithExtraMember* object);

    int extra_member_val;
};
example.cpp

#include "example.h"

ExternalClass e;

Object::Object() {}

void Object::pass_self_to_external_class() {
    e.do_something_with_object(this);
}

ObjectWithExtraMember::ObjectWithExtraMember() {
    extra_member = 45;
}

ExternalClass::ExternalClass() {
    extra_member_val = 0;
}

void ExternalClass::do_something_with_object(Object* object) {
    extra_member_val = 0;
}

void ExternalClass::do_something_with_object(ObjectWithExtraMember* object) {
    extra_member_val = object->extra_member;
}

如果

ObjectWithExtraMember
的实例调用
pass_self_to_external_class
,有没有办法让
pass_self_to_external_class
调用
ExternalClass::do_something_with_object(ObjectWithExtraMember* object)
而不是
ExternalClass::do_something_with_object(Object* object)
?我目前在实际项目中使用的解决方案是创建一个函数
ObjectWithExtraMember::pass_self_to_external_class
,其行为与
Object
版本完全相同,但是是否可以强制继承版本传递派生类的实例而不需要这样做?

c++ inheritance overloading
1个回答
0
投票

我认为我们可以使用 CRTP 来处理这个问题。

class ExternalClass;

template<typename T>
class Object {
public:

    Object() {}

    void pass_self_to_external_class(ExternalClass &e);

    T* get_instance() {
        return static_cast<T*>(this);
    }
};

class ObjectWithExtraMember : public Object<ObjectWithExtraMember> {
public:
    
    ObjectWithExtraMember() {
        extra_member = 45;
    }

    int extra_member;
};

class ExternalClass {
public:
    ExternalClass() {
        extra_member_val = 0;
    }

    template<class T>    
    void do_something_with_object(Object<T>* object) {
extra_member_val = object->get_instance()->extra_member;
}
    // void do_something_with_object(ObjectWithExtraMember* object);

    int extra_member_val;
};

template<typename T>
void Object<T>::pass_self_to_external_class(ExternalClass &e) {
    if constexpr (std::is_void<T>::value == false) {
        e.do_something_with_object(get_instance());
    } else {
        e.extra_member_val = 0;
    }
}

测试代码。

int main(int, char**)
{
    ExternalClass e;
    Object<void> base;
    base.pass_self_to_external_class(e);
    cout << e.extra_member_val << endl;

    ObjectWithExtraMember derived;
    
    derived.pass_self_to_external_class(e);
    cout << e.extra_member_val << endl;

    ObjectWithExtraMember_plus derived1;
    derived1.pass_self_to_external_class(e);

    cout << e.extra_member_val << endl;
    return 0;
}
© www.soinside.com 2019 - 2024. All rights reserved.