我无法使用抽象类作为值来正确编译抽象类。理想情况下,我想做类似以下的事情
unordered_map<string, Process_Base> func_map;
Process_Base的位置如何
//Contained in Process_Base.hpp
class Process_Base{
public:
virtual ~Process_Base(){};
virtual void process() const = 0;
};
和子类看起来像
#include "Process_Base.hpp"
class Process_Message : public Process_Base {
public:
~Process_Message(){};
virtual void process();
};
#include <stdio.h>
#include <string.h>
#include "Process_Base.hpp"
class Process_Message{
public:
void process(){
printf("%s", "Hello");
}
};
这背后的想法是我能够将子类添加到地图中,并且有一个简单的函数可以查看键值并调用子类&#39;过程功能。
当我使用
在CentOS 5.8上编译时g++44 -Wall -c -std=c++0x -I/usr/include -g Source.cpp
我收到以下一系列错误
In file included from /usr/lib/gcc/x86_64-redhat-linux6E/4.4.6/../../../../include/c++/4.4.6/bits/stl_algobase.h:66,
from /usr/lib/gcc/x86_64-redhat-linux6E/4.4.6/../../../../include/c++/4.4.6/bits/char_traits.h:41,
from /usr/lib/gcc/x86_64-redhat-linux6E/4.4.6/../../../../include/c++/4.4.6/string:42,
from Source.cpp:2:
/usr/lib/gcc/x86_64-redhat-linux6E/4.4.6/../../../../include/c++/4.4.6/bits/stl_pair.h: In instantiation of ‘std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, Process_Base>’:
/usr/lib/gcc/x86_64-redhat-linux6E/4.4.6/../../../../include/c++/4.4.6/bits/stl_function.h:482: instantiated from ‘std::_Select1st<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, Process_Base> >’
/usr/lib/gcc/x86_64-redhat-linux6E/4.4.6/../../../../include/c++/4.4.6/tr1_impl/hashtable_policy.h:790: instantiated from ‘std::__detail::_Hash_code_base<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, Process_Base>, std::_Select1st<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, Process_Base> >, std::equal_to<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::hash<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, false>’
/usr/lib/gcc/x86_64-redhat-linux6E/4.4.6/../../../../include/c++/4.4.6/tr1_impl/hashtable:137: instantiated from ‘std::_Hashtable<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, Process_Base>, std::allocator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, Process_Base> >, std::_Select1st<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, Process_Base> >, std::equal_to<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::hash<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, false, false, true>’
/usr/lib/gcc/x86_64-redhat-linux6E/4.4.6/../../../../include/c++/4.4.6/tr1_impl/unordered_map:48: instantiated from ‘std::__unordered_map<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, Process_Base, std::hash<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, Process_Base> >, false>’
/usr/lib/gcc/x86_64-redhat-linux6E/4.4.6/../../../../include/c++/4.4.6/tr1_impl/unordered_map:190: instantiated from ‘std::unordered_map<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, Process_Base, std::hash<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, Process_Base> > >’
Source.cpp:14: instantiated from here
/usr/lib/gcc/x86_64-redhat-linux6E/4.4.6/../../../../include/c++/4.4.6/bits/stl_pair.h:73: error: cannot declare field ‘std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, Process_Base>::second’ to be of abstract type ‘Process_Base’
Process_Base.hpp:1: note: because the following virtual functions are pure within ‘Process_Base’:
Process_Base.hpp:5: note: virtual void Process_Base::process() const
make: *** [Source.o] Error 1
有人可以帮助我理解这些编译错误。尝试制作函数指针而不是子类的映射会更好吗?如果是这样,我将如何在Process Message等类中创建指向函数的指针映射。
答案 0 :(得分:5)
抽象类不能直接实例化,但是你可以指向它们的值,它们的值最终被实例化(非抽象)子类。
class Abstract {
public:
virtual void Foo() = 0;
};
Abstract x; // error
Abstract* p; // fine
class Derived : Abstract {
public:
virtual void Foo() {
printf("Hello!\n");
}
};
p = new Derived();
// or:
Derived d;
p = &d;
因此,您也不能拥有抽象类的容器 - 只能指向抽象类。
unordered_map<string, Process_Base*> func_map;
根据您填充(或尝试填充)原始func_map
的方式,使用unique_ptr
代替常规指针可能会有所帮助。
unoredered_map<string, unique_ptr<Process_Base>> func_map;
通过这种方式,您可以执行func_map["foo"] = new Derived()
之类的操作,而无需担心明确调用delete func_map["foo"]
。