c ++未定义的对具有继承g ++

时间:2017-10-20 17:41:31

标签: c++ inheritance shared-ptr undefined-reference

我有一个非常简单的代码,关于继承自另一个(请求)的3个类(添加,更新,删除)。

这些类在另一个名为interpreter的实例化中,作为shared_ptrs与make_shared一起实例化。我使用CMake构建整个项目,Interpreter不属于与Request相同的共享库。

事情是,当我在MacOS上使用g ++(调用Clang)编译它时,它运行得很好。现在,当我尝试使用g ++(真实的)在Unix上导出它时,它会在链接期间抛出此错误:

src/interpreter/libinterpreter_obj.so : undefined reference to 'request::Remove::Remove(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)'
src/interpreter/libinterpreter_obj.so : undefined reference to 'request::Add::Add(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)'
src/interpreter/libinterpreter_obj.so : undefined reference to 'request::Update::Update(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)'

Clang可以编译和运行而不是g ++的事实与我对Clang的选项有关:-undefined dynamic_lookup

所以链接器试图在libinterpreter_obj.so中找到那些构造函数,它应该在librequest_obj.so中找到它们

此外,这里有一个简单的方法来重现问题(因为三个类的错误是相同的,所以只包含Remove):

CMakeLists.txt:

cmake_minimum_required(VERSION 2.8)
project(ANALYSEUR_STX C CXX)

set(CMAKE_MACOSX_RPATH 1)
set(CMAKE_CXX_COMPILER "g++")
set(CMAKE_CXX_FLAGS "-Wall -Wextra -Werror -pedantic -std=c++14")

find_package(Threads REQUIRED) #Technicaly needed for shared_ptr

include_directories(src/)

add_subdirectory(src/request)
add_subdirectory(src/interpreter)

set(ALL
  src/main.cc)

add_executable(main ${ALL})

target_link_libraries(main
  request_obj
  interpreter_obj
  ${CMAKE_THREAD_LIBS_INIT})

src / interpreter / interpreter.hh:

# pragma once
#include <string>

namespace interpreter
{
  class Interpreter
  {
    public:
      Interpreter();
      std::string request();

    private:
      std::string item_;
  };
}

src / interpreter / interpreter.cc:

#include <memory>
#include "interpreter/interpreter.hh"
#include "request/request.hh"
#include "request/remove.hh"

namespace interpreter
{
  Interpreter::Interpreter() {}

  std::string Interpreter::request()
  {
    std::shared_ptr<request::Request> rq;
    rq = std::make_shared<request::Remove>(item_);
    return (rq->gen_request());
  }
}

src / interpreter / CMakeLists.txt:

set(SRC
  interpreter.cc)

add_library(interpreter_obj SHARED ${SRC})

src / request / request.hh:

# pragma once
#include <string>

namespace request
{
  class Request
  {
    public:
      Request(std::string item);
      virtual ~Request() = default;
      virtual std::string gen_request() = 0;

    protected:
      std::string item_;
  };
}

src / request / request.cc:

#include "request.hh"

namespace request
{
  Request::Request(std::string item)
    : item_(item)
  {}
}

src / request / remove.hh:

# pragma once
#include "request/request.hh"

namespace request
{
  class Remove: public Request
  {
    public:
      Remove(std::string item);
      std::string gen_request() override;
  };
}

src / request / remove.cc:

#include "request/remove.hh"

namespace request
{
  Remove::Remove(std::string item)
    : Request(item)
  {}

  std::string Remove::gen_request() { return ("remove"); }
}

src / request / CMakeLists.txt:

set(SRC
  request.cc
  remove.cc)

add_library(request_obj SHARED ${SRC})

src / main.cc:

#include "interpreter/interpreter.hh"

int main()
{
  interpreter::Interpreter itp;
}

编译:

mkdir build
cd build/
cmake ..
make

感谢您的帮助!

0 个答案:

没有答案