C++ C++;类方法,返回向量<;子类>;
我在为一个类编写一个方法时遇到了一些问题。我有班级符号和班级终端。类终端扩展了类符号,但是类符号的一个方法需要返回一个向量。例如:C++ C++;类方法,返回向量<;子类>;,c++,stl,polymorphism,C++,Stl,Polymorphism,我在为一个类编写一个方法时遇到了一些问题。我有班级符号和班级终端。类终端扩展了类符号,但是类符号的一个方法需要返回一个向量。例如: #ifndef SYMBOL_H #define SYMBOL_H #include "terminal.h" #include <vector> using namespace std; class symbol { public: vector<terminal> first(); virtua
#ifndef SYMBOL_H
#define SYMBOL_H
#include "terminal.h"
#include <vector>
using namespace std;
class symbol {
public:
vector<terminal> first();
virtual void polymorphable();
};
#endif
但是,在执行此操作时,我在构建时会遇到两个错误,其中一个错误在前面:“terminal”:未声明的标识符(位于定义向量函数的行上),以及“symbol”:基类未定义(位于具有terminal类定义的行上)
如何解决“a需要b”、“b需要a”问题?使用避免循环依赖关系
class terminal;
class symbol
{
std::vector<terminal> first();
// ...
};
类终端;
类符号
{
std::vector first();
// ...
};
有一种推测,这种方法是按照C++标准定义的。
@本·沃伊特指出:
C++03标准第17.6.4.8节说:
“特别是,在以下情况下,效果是未定义的:……如果在实例化模板组件时将不完整的类型用作模板参数,除非该组件特别允许
正在讨论
std::vector f();
是否是std::vector
的一个实例。如果那里的答案证明是,那么这个答案就没有用,我将删除它,否则它仍然有效。使用避免循环依赖关系
class terminal;
class symbol
{
std::vector<terminal> first();
// ...
};
类终端;
类符号
{
std::vector first();
// ...
};
有一种推测,这种方法是按照C++标准定义的。
@本·沃伊特指出:
C++03标准第17.6.4.8节说:
“特别是,在下列情况下,影响是未定义的:。。。如果在实例化模板组件时将不完整类型用作模板参数,除非该组件特别允许
是否
std::vector f()代码>是std::vector
的一个实例,正在讨论。如果答案证明是正确的,那么这个答案就无效,我将删除相同的答案,否则这个答案仍然有效。我觉得奇怪的是,重复出现的模板模式可以让你摆脱这个问题:
template<typename terminal_type>
class symbol_pattern
{
public:
std::vector<terminal_type> first();
virtual void polymorphable();
};
class terminal : public symbol_pattern<terminal>
{
};
typedef symbol_pattern<terminal> symbol;
模板
类符号
{
公众:
std::vector first();
虚空可变形();
};
类终端:公共符号\u模式
{
};
typedef符号\图形符号;
我认为奇怪的重复模板模式可以让您摆脱这种模式:
template<typename terminal_type>
class symbol_pattern
{
public:
std::vector<terminal_type> first();
virtual void polymorphable();
};
class terminal : public symbol_pattern<terminal>
{
};
typedef symbol_pattern<terminal> symbol;
模板
类符号
{
公众:
std::vector first();
虚空可变形();
};
类终端:公共符号\u模式
{
};
typedef符号\图形符号;
编辑:标准可能不允许以下内容(参见注释)。在这种情况下,您根本无法拥有适当的循环依赖关系:如果a
的大小取决于B
类型的成员的大小,但是B
的大小取决于a
类型的成员的大小,那么这样的定义根本没有意义
不过,我不能完全确定这是否适用于您的情况,因为您只声明了一个返回类型不完整的函数,这是允许的。见服务员;希望我们能得到一个明确的答案
只需向前声明终端
:
class terminal;
class symbol
{
std::vector<terminal> first();
// ...
};
类终端;
类符号
{
std::vector first();
// ...
};
您可以向前声明任何只需要是不完整类型的内容。不完整类型可用于形成指针、引用、函数签名。只有在使用该类型的变量时,才需要知道完整类型。编辑:标准可能不允许以下情况(请参见注释)。在这种情况下,您根本无法拥有适当的循环依赖关系:如果a
的大小取决于B
类型的成员的大小,但是B
的大小取决于a
类型的成员的大小,那么这样的定义根本没有意义
不过,我不能完全确定这是否适用于您的情况,因为您只声明了一个返回类型不完整的函数,这是允许的。见服务员;希望我们能得到一个明确的答案
只需向前声明终端
:
class terminal;
class symbol
{
std::vector<terminal> first();
// ...
};
类终端;
类符号
{
std::vector first();
// ...
};
您可以向前声明任何只需要是不完整类型的内容。不完整类型可用于形成指针、引用、函数签名。只有在使用该类型的变量时,才需要知道完整的类型。Base
类不需要知道有关派生的类的任何信息。这是面向对象设计的一个重要原则。您可能会将基类更改为:
class symbol {
public:
vector<symbol*> first();
virtual void polymorphable();
};
Base
类不需要了解任何有关派生类的信息。这是面向对象设计的一个重要原则。您可能会将基类更改为:
class symbol {
public:
vector<symbol*> first();
virtual void polymorphable();
};
前向声明+智能指针(尽管这将在堆上而不是堆栈上存储内容…可能是不可取的)
\ifndef符号
#定义符号
#包括
#包括
使用名称空间std;
类终端;//像这样做一个提前声明
类符号{
公众:
向量优先();
虚空可变形();
};
#恩迪夫
前向声明+智能指针(尽管这现在将在堆上而不是堆栈上存储内容…可能是不可取的)
\ifndef符号
#定义符号
#包括
#包括
使用名称空间std;
类终端;//像这样做一个提前声明
类符号{
公众:
向量优先();
虚空可变形();
};
#恩迪夫
而不是只有一个成员函数返回一个容器,考虑拥有<
#include <vector>
class terminal; <--- TELLING THE COMPILER MAY USE terminal in the future.
class symbol
{
std::vector<terminal> first(); <--- NOTE THE COMPILER DOES NOT NEED TO KNOW HOW TO CONSTRUCT EITHER
// ...
};
class terminal: public symbol < --- TELLS COMPILER THAT terminal INHERITS symbol i.e. CONTAINING THE METHOD first
{
int wibble;
};
int main()
{
symbol s;
return 0;
}