C 成员从模板类型的派生类访问

C++ member access from a derived class of a templated type

本文关键字:派生 访问 类型 成员      更新时间:2023-10-16

长话短说,我想要的是在基类中声明模板类型,并能够访问该类型A<T>,以便基类B包含它,并且派生的类C能够以C::A<T>访问它。我确实尝试声明class B内部的int,并且可以从派生的C类中访问为C::int,这是错误!

||In constructor ‘D::D()’:|
|74|error: no match for ‘operator=’ (operand types are ‘A<C*>’ and ‘A<B*>’)|
|4|note: candidate: A<C*>& A<C*>::operator=(const A<C*>&)|
|4|note:   no known conversion for argument 1 from ‘A<B*>’ to ‘const A<C*>&’|

这是编译的代码(注释A<B*> i;和Uncomment A<C*> i;以获取错误(。

#include <iostream>
//class with a template parameter
template <class a>
class A
{
    private:
        int somevalue;
    public:
    A(){}
    ~A(){}
    void print()
    {
        std::cout<<somevalue<<std::endl;
    }
};
//1. could forward declare
class C;
class B
{
    protected:
        A<B*> i;
        //2. and then use
        //A<C*> i;
    public:
        B(){}
        ~B(){}
        A<B*> get()
        {
            return i;
        }
        /*
        //3. use this return instead
        A<C*> get()
        {
            return i;
        }
        */
};
//specialization of B that uses B's methods variables
class C : public B
{
    protected:
    public:
        C(){}
        virtual ~C(){}
        void method()
        {
            B::i.print();
        }
};
//class D that inherits the specialization of C
class D : public C
{
    private:
        A<B*> i;//works
        //4. but I want the inherited type to work like
        //A<C*> i;// so that the type C* is interpreted as B*
    public:
    D()
    {
        this->i = C::i;
    }
    ~D(){}
};
///////////////////////////////////////////////////////////////////////
int main()
{
    D* d = new D();
    delete d;
    return 0;
}

但是好吧,如果我们尝试了此std::list<template parameter> LIST,然后将其插入其中怎么办?这就是问题A<T>std::list

据我了解您的问题,现在您似乎拥有std::list<Base *>(B将CC_15更名为Base,sor Clarity(,并希望填充std::list<Concrete*>(将C更名为Concrete,它是从Base派生的(。

为此,您需要迭代Base*指针,检查每个指针是否可以 downcast Concrete*,如果可以将其添加到std::list<Concrete*>中。您需要考虑一下如果降低的失败也该怎么办。

为了使所有这些工作都必须是多态基类,也就是说,它必须包含一个虚拟成员函数(不要忘记使destructor virtual virtual virtual(。还要注意,这听起来像是一场灾难,等待在管理这些指针的所有权方面发生。

template<typename Base, typename Concrete>
std::list<Concrete*> downcast_list (std::list<Base*> const & bases) {
 std::list<Concrete*> result;
  for (auto const base_ptr : bases) {
    Concrete * concrete_ptr = dynamic_cast<Concrete*>(base_ptr);
    if (concrete_ptr != nullptr) {
      result.push_back(concrete_ptr);
    } else {
      // Error or ignore?
    }
  }
  return result;
}

注意:它的更惯用版本将使用迭代器。

我找到了问题的模式,它实际上很简单,它是封装类类型a的基础(这是要传递的模板参数,尝试查看我的我问题作为class a的引用(。图案如下所示,通常是我想要的。我在此网页上使用模板之间的继承在该网页上找到了它的第7.5章,标题为"面向对象"软件设计和施工与Dennis Kafura的C 。为了将来参考,我将在编辑的代码下方复制它,以防其他人需要它。

template <class a> 
class B 
{
    private:      
    public:
        B();     
        ~B();
};
template <class a> 
class C : public B<a>
{
   public:
    C();
    ~C();
};

这是它改编的代码。

template <class QueueItem> class Queue 
{
   private:
      QueueItem buffer[100];
      int head, tail, count;
    public:
                Queue();
      void      Insert(QueueItem item);
      QueueItem Remove();
               ~Queue();
};
template <class QueueItem> class InspectableQueue : public Queue<QueueItem>
{
   public:
               InspectableQueue();
     QueueItem Inspect();  // return without removing the first element
              ~InspectableQueue();
};

尝试更改以下内容:

#include <iostream>
//class with a template parameter
template <class a>
class A {
private:    
    int somevalue;    
public:    
    A(){}
    ~A(){}
    void print() {
        std::cout<<somevalue<<std::endl;
    }
};

//1. could forward declare
class C;
class B {
protected:    
    A<B*> i;
    //2. and then use
    //A<C*> i;    
public:    
    B(){}
    ~B(){}
    A<B*> get() {
        return i;
    }
    /*/3. use this return instead
    A<C*> get() {
       return i;
    } */
};

//specialization of B that uses B's methods variables
class C : public B {
protected:
public:    
    C(){}
    virtual ~C(){}
    void method() {
        B::i.print();
    }
};    

//class D that inherits the specialization of C
class D : public C {
private:   
    A<B*> i;//works
    //4. but I want the inherited type to work like
    //A<C*> i;// so that the type C* is interpreted as B*
public:    
    D() {
        this->i = C::i;
    }
    ~D(){}
};

   int main() {
    D* d = new D();    
    delete d;    
    return 0;
}

这样的东西:

#include <iostream>
//class with a template parameter
template <typename T>
class Foo {
private:    
    T value_;    
public:    
    Foo(){} // Default
    Foo( T value ) : value_(value) {}
    ~Foo(){}
    void print() {
        std::cout<< value_ << std::endl;
    }
};

class Derived;
class Base {
protected:
    Foo<Base*> foo_;
    Base(){} // Default;
    virtual ~Base(){}
    // Overload This Function
    template<typename T = Base>
    /*virtual*/ Foo<T*> get();
    /*virtual*/ Foo<Base*> get() { return this->foo_; }
    /*virtual*/ Foo<Derived*> get();
};

class Derived : Base {
public:
    Derived() {}
    virtual ~Derived() {}
    void func() {
        Base::foo_.print();
    }
    void Foo<Derived*> get() override { return this->foo_; } 
 };

,这是我尝试回答您的问题的范围。

  • 有些对象在代码中没有使用
  • 有没有被调用的方法。
  • 很难理解方向/间接 您对继承树的意思。
  • 您是从base类继承的,没有virtual destructor
  • 以及我现在无法想到的其他一些事情。

我很乐意尝试帮助您;但这是我目前所显示的内容。

编辑 - 我对base & derived类进行了更改,并将virtual关键字删除到Overloaded功能模板声明 - 属于这些类的定义。