C++ 派生结构和父结构中指向自身的指针

C++ 派生结构和父结构中指向自身的指针,c++,struct,polymorphism,C++,Struct,Polymorphism,我有三个结构,一个包含属性的“父”结构,以及两个从父结构派生的结构,其中我只有方法。基本上,结构的内容总是相同的,但我希望在不同的情况下对同一方法进行不同的实现 示例代码: struct Unit { int id; Unit* next; }; struct CUnit: Unit { bool some_complicated_condition(); // client impl }; struct SUnit: Unit { bool some_

我有三个结构,一个包含属性的“父”结构,以及两个从父结构派生的结构,其中我只有方法。基本上,结构的内容总是相同的,但我希望在不同的情况下对同一方法进行不同的实现

示例代码:

struct Unit {

    int id;
    Unit* next;
};

struct CUnit: Unit {

    bool some_complicated_condition(); // client impl
};

struct SUnit: Unit {

    bool some_complicated_condition(); // server impl
};

CUnit* get_client_unit_by_id(int id) {

    CUnit* unit = g_client_units;
    
    while (unit) {
    
        if (unit->id == id && unit->some_complicated_condition()) {
            return unit;
        }
        
        unit = unit->next;
    }
    
    return nullptr;
}
当然,在编译此文件时,会出现以下错误:
错误C2440:“=”:无法从“Unit*”转换为“CUnit*”

注意:从基础转换为派生需要动态转换或静态转换

我可以像这样施放
unit->next
(CUnit*)unit->next
,但如果可能的话,我会尽量避免这种情况。我搜索过了,但找不到答案。这仅仅是因为两个实现之间的结构的内容是相同的,我希望能够在不强制转换的情况下按原样使用它们


所以我想知道,有没有什么方法可以重新定义我的结构,让它开箱即用?

来回答你最初的问题(似乎没有人愿意回答这个问题,而只是给你关于如何编写代码的意见):是的,你可以做你想做的事,它包括按要存储在下一个中的指针对单元进行模板化:

请注意,此模式非常常见,因此有一个名称:奇怪的重复模板模式,或CRTP。阅读所有关于它的信息


“如果可能的话,我会尽量避免”为什么?如果您完全确定
unit->next
真的将是
CUnit
,那么抛出指针没有错。也许最干净的方法是执行
operator++
overload@vikAy>评论了错误的问题?:)@布莱恩,你是对的,我知道。我只是不想这么做,说得很清楚,只是出于句法上的原因。i、 我不希望在我的代码中出现杂乱无章的角色转换,没有任何技术原因。我觉得这是不可能做到的,但我想我会问一下,看看会出现什么结果。你可以将
一些复杂的条件作为纯虚拟方法添加到基类中。那你就不需要任何演员了。嘿,谢谢你的回答!事实上,大多数评论都在质疑我为什么这么做,而不仅仅是回答这个问题。所提供的示例只是从大量上下文中剥离出来的代码,在我实际尝试做的事情背后有很多很好的理由,但这里的任何人都不关心。你的答案看起来不错,我觉得很糟糕,有人否决了你,我会研究你的两个解决方案。我认为模板解决方案几乎就是我想要的,但我还需要能够使用基本单元结构,因为它代表一个“中立”单元,它包含服务器和客户端之间共享的方法。它也是在服务器和客户端之间共享的代码中使用的结构。第二种解决方案当然有效,我自己也想到过,但有点烦人。但我最终可能会走这条路,我知道你只是给出了一个非常模糊的代码表示,你宁愿改变得尽可能少,只是想给你我想到的可能性。祝你好运
template < class t_TyNext >
struct Unit {

    int id;
    t_TyNext * next;
};

struct CUnit: Unit< CUnit > {

    bool some_complicated_condition(); // client impl
};

struct SUnit: Unit< SUnit > {

    bool some_complicated_condition(); // server impl
};

CUnit* g_client_units;

CUnit* get_client_unit_by_id(int id) {

    CUnit* unit = g_client_units;
    
    while (unit) {
    
        if (unit->id == id && unit->some_complicated_condition()) {
            return unit;
        }
        
        unit = unit->next;
    }
    
    return nullptr;
}
struct Unit {
    int id;
    Unit* next;
};

struct CUnit: protected Unit 
{
    using Unit::id;
    bool some_complicated_condition(); // client impl
    CUnit * GetNext() { return (CUnit *)Unit::next; }
};

struct SUnit: protected Unit {
    using Unit::id;
    bool some_complicated_condition(); // server impl
    SUnit * GetNext() { return (SUnit *)Unit::next; }
};

CUnit* get_client_unit_by_id(int id) {

    CUnit* unit = g_client_units;
    
    while (unit) {
    
        if (unit->id == id && unit->some_complicated_condition()) {
            return unit;
        }
        
        unit = unit->GetNext();
    }
    
    return nullptr;
}