来自模板化类型的派生类的C ++成员访问

时间:2017-06-24 05:49:33

标签: c++ templates inheritance derived-class

长话短说,我想要的是在基类中声明模板化类型并能够访问该类型A<T>,以便基类B包含它和派生类{ {1}}可以C访问它。我确实尝试在C::A<T>内声明int,可以从派生的class B类中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;以获取错误)。

A<C*> i;

3 个答案:

答案 0 :(得分:2)

  

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

据我了解您的问题,您现在似乎有一个std::list<Base *>(为了清晰起见,已重命名为BBase,并希望填写std::list<Concrete*>(已重命名为{ {1}}到C,它来自Concrete)。

为此,您需要迭代Base指针,检查每个指针是否可以向下转换Base*,如果是,则将其添加到Concrete* }}。如果贬低失败,你需要考虑该怎么做。

要使所有这些工作,std::list<Concrete*>需要是多态基类,那就是它必须包含一个虚拟成员函数(不要忘记将析构函数设为虚拟) 。另请注意,这听起来像是在管理这些指针的所有权方面等待发生的灾难。

Base

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

答案 1 :(得分:1)

我找到了我的问题的模式,它实际上非常简单,它作为封装类型a的基础(这是一个模板参数传递,试着看看我的问题作为class a的参考。模式如下所示,它通常是我想要的。我在这个网页Using Inheritance Between Templates chapter 7.5 from the book entitled OBJECT-ORIENTED SOFTWARE DESIGN and CONSTRUCTION with C++ by Dennis Kafura找到了它。我将其复制到编辑后的代码下面,以备日后参考,以防其他人需要它。

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();
};

答案 2 :(得分:-1)

尝试更改此内容:

  
#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关键字删除为重载的函数模板声明 - 属于这些类的定义。