设置:
class A {
public:
void a() {}
};
class B {
public:
void b() {}
};
class C: public A, public B {
public:
void c() {}
};
我应该能够做什么(我认为):
C* foo = new C();
foo->b();
我从 GCC 得到以下链接器错误:
`... undefined reference to 'C::b(void)'`
如果我使用显式范围解析,它会起作用,如:
C* foo = new C();
foo->B::b();
A、B 和 C 没有共享具有相似签名的成员,所以我知道没有隐藏任何内容。两个问题:
1) 从理论上讲,为什么我不能隐式访问公共(public)基类成员?
2) 在实践中我可以做什么(如果有的话)来避免这种烦人的语法?
我可以继续使用显式语法进行开发(尽管我宁愿摆脱它),但我更希望在这里学习一些关于我的(显然不正确的)C++ 公共(public)继承知识。
干杯!
编辑:抱歉,更新了示例代码 - 我的原始代码中出现了一些错误。
EDIT2:这是真实代码的(相关部分): 来自 src/creature.h:
#include "container.h"
#include "identifiers.h"
class Creature: public Identifiers, public Container {
public:
Creature( void );
Creature( const Creature& ref );
virtual ~Creature( void );
};
来自 src/identifier.h:
class Identifiers {
public:
Identifiers( void );
Identifiers( const Identifiers& ref );
~Identifiers( void );
};
来自 src/container.h:
class Container {
public:
Container( std::string (Object::*getName)( void ) const );
Container( const Container& ref );
~Container( void );
void add( Object* object );
void add( const std::list<Object*>& objects );
void remove( Object* object );
void remove( const std::list<Object*>& objects );
};
来自 src/container.cpp:
Container::Container( std::string (Object::*getName)( void ) const ) {
_getName = getName;
return;
}
Container::Container( const Container& ref ) {
_getName = ref._getName;
return;
}
Container::~Container( void ) {
while ( !objectList().empty() ) {
delete objectList().front();
objectList().pop_front();
}
return;
}
void Container::add( Object* object ) {
objectList().push_back( object );
return;
}
void Container::add( const std::list<Object*>& objects ) {
objectList().insert( objectList().end(), objects.begin(), objects.end() );
return;
}
void Container::remove( Object* object ) {
objectList().remove( object );
return;
}
void Container::remove( const std::list<Object*>& objects ) {
for ( std::list<Object*>::const_iterator it = objects.begin(); it != objects.end(); ++it ) {
remove( *it );
}
return;
}
来自应用程序本身:
bool CmdWear::execute( Creature* creature, const std::string& args ) {
std::list<Object*> objects;
Object* removed = NULL;
std::string error;
objects = creature->searchObjects( args );
for ( std::list<Object*>::iterator it = objects.begin(); it != objects.end(); ++it ) {
if ( creature->wear( *it, error, removed ) ) {
creature->remove( *it );
}
}
return true;
}
注意事项:
1) 此处显示的所有方法都在其相应的 .cpp 文件中定义。
2) 每个关联的目标文件都可以正常编译。只有链接器在将所有目标文件链接在一起的最后一步失败。
3) GCC 吐出:对 `Creature::remove(Object*)' 的 undefined reference ,除非我明确限定范围:
creature->Container::remove( *it );
生成文件:
PROJECT = symphony
CPPC = g++
FLAGS_DEV = -ggdb3 -ansi -Wall -Werror -pedantic-errors
LIBS = `pcre-config --libs` `mysql_config --libs`
SRC_DIR = src
OBJ_DIR = obj
BIN_DIR = .
SRC_FILES := $(wildcard $(SRC_DIR)/*.cpp)
OBJ_FILES := $(patsubst src/%.cpp,obj/%.o,$(SRC_FILES))
dev: $(OBJ_FILES)
$(CPPC) $(LIBS) $(FLAGS_DEV) $(OBJ_FILES) -o $(BIN_DIR)/$(PROJECT)
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
$(CPPC) -c $(FLAGS_DEV) $< -o $@
最佳答案
您不能调用未定义的函数。 gcc 就是这么告诉你的。并且 foo::B->b();
不是有效的 C++。它不能用 g++
或 cl.exe
编译。
如果你写了
public:
void b() {}
它会起作用。
关于c++ - 为什么需要这种明确的范围解析?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1886030/