C 成员从模板类型的派生类访问
C++ member access from a derived class of a templated type
长话短说,我想要的是在基类中声明模板类型,并能够访问该类型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功能模板声明 - 属于这些类的定义。
- 如何使用单独文件中的派生类访问友元函数对象
- 为什么此派生对象无法访问基类的后递减方法?
- C++:为什么无法在派生类中访问受保护的构造函数?
- 如何使用 C++ 中的继承函数访问派生类中的局部变量
- 派生的 wxPanel 控件如何访问其中包含 wxDialog 中的数据?
- 从纯虚拟类 (A) 派生的指针无法访问来自纯类 (B) 的重载方法
- C ++基础私有方法在将自身转换为派生类后可以访问吗?
- 按基类对象访问派生类资源时出错
- 使(虚拟)函数在大多数派生类中无法访问中间基类中可访问,定义良好?
- 从模板化父类中的派生内部类访问受保护的成员变量
- 如何从派生类访问基类中的重载运算符?
- 两个抽象类,派生自同一个基类.如何访问从一个抽象类到另一个抽象类的指针
- C++11: 如何访问派生类中的基类成员?
- 访问派生类的 QMetaObject
- 使用基类对象访问派生的仅类方法
- 如何在 c++ 中通过基类引用访问派生类的对象?
- 派生类无法访问基类的受保护成员
- 如何在 c++ 中使用多态性访问派生类字段?
- 为了访问方法,从基类动态转换为派生类
- C++继承从基类指针访问派生类中的非虚拟函数