c++ - 为什么需要这种明确的范围解析?

标签 c++ inheritance gcc scope visibility

设置:

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/

相关文章:

c++ - 在这种情况下如何避免代码重复问题?

C++编译问题

c++ - iOS:更新到 Xcode 8.3 后编译器中的 C++ 警告

javascript - 对象继承/导入问题

c - 这个集会怎么可能?

gcc 中的更改/优化标志 gcc/C 的持久性

c++ - 在 Qt 中,如何将 QString 注册到我的系统剪贴板,包括引用和非引用?

C# - 泛型和继承问题

java - jackson 忽略外部库中父类(super class)的所有属性

为 "-std=gnu90"编译 C 项目错误