C++ 프로그램을 작성할 때, 내 I& # 39 m getting 오류 메시지
>. 정의되지 않은 참조입니다 & # 39, 프터블.
이 문제의 원인은 무엇입니까? 해결하십시오 어떻게 합니까?
그렇게 하면, 다음과 같은 코드를 가져오는 오류를 I& 있는 # 39 m (해당 클래스의 질문은 가임모두리.) 그 동안 나를 이해할 수 없는 문제가 있다. 처음에는 생각해봤죠 전송되었기 관련됨 잊고 있는 게 아니라, 가상 함수 전달자로써 바디입니다 이들보 목마르겠구나 전부 다 알고 있다, 체인은 슬라이드에서는 조금 긴 것이지만, 상속 관련 소스 코드. 내가 잘 모르는 i& # 39 m, 기타 정보를 제공해야 합니다.
참고: 이 일이, it&; d # 39 는 구성자를 대화상자에서는 오류: 것 같다.
내 코드:
class CGameModule : public CDasherModule {
public:
CGameModule(Dasher::CEventHandler *pEventHandler, CSettingsStore *pSettingsStore, CDasherInterfaceBase *pInterface, ModuleID_t iID, const char *szName)
: CDasherModule(pEventHandler, pSettingsStore, iID, 0, szName)
{
g_pLogger->Log("Inside game module constructor");
m_pInterface = pInterface;
}
virtual ~CGameModule() {};
std::string GetTypedTarget();
std::string GetUntypedTarget();
bool DecorateView(CDasherView *pView) {
//g_pLogger->Log("Decorating the view");
return false;
}
void SetDasherModel(CDasherModel *pModel) { m_pModel = pModel; }
virtual void HandleEvent(Dasher::CEvent *pEvent);
private:
CDasherNode *pLastTypedNode;
CDasherNode *pNextTargetNode;
std::string m_sTargetString;
size_t m_stCurrentStringPos;
CDasherModel *m_pModel;
CDasherInterfaceBase *m_pInterface;
};
에서 상속됩니다.
class CDasherModule;
typedef std::vector<CDasherModule*>::size_type ModuleID_t;
/// \ingroup Core
/// @{
class CDasherModule : public Dasher::CDasherComponent {
public:
CDasherModule(Dasher::CEventHandler * pEventHandler, CSettingsStore * pSettingsStore, ModuleID_t iID, int iType, const char *szName);
virtual ModuleID_t GetID();
virtual void SetID(ModuleID_t);
virtual int GetType();
virtual const char *GetName();
virtual bool GetSettings(SModuleSettings **pSettings, int *iCount) {
return false;
};
private:
ModuleID_t m_iID;
int m_iType;
const char *m_szName;
};
이를 통해 상속됩니다.
namespace Dasher {
class CEvent;
class CEventHandler;
class CDasherComponent;
};
/// \ingroup Core
/// @{
class Dasher::CDasherComponent {
public:
CDasherComponent(Dasher::CEventHandler* pEventHandler, CSettingsStore* pSettingsStore);
virtual ~CDasherComponent();
void InsertEvent(Dasher::CEvent * pEvent);
virtual void HandleEvent(Dasher::CEvent * pEvent) {};
bool GetBoolParameter(int iParameter) const;
void SetBoolParameter(int iParameter, bool bValue) const;
long GetLongParameter(int iParameter) const;
void SetLongParameter(int iParameter, long lValue) const;
std::string GetStringParameter(int iParameter) const;
void SetStringParameter(int iParameter, const std::string & sValue) const;
ParameterType GetParameterType(int iParameter) const;
std::string GetParameterName(int iParameter) const;
protected:
Dasher::CEventHandler *m_pEventHandler;
CSettingsStore *m_pSettingsStore;
};
/// @}
#endif
[Mgcc FAQ] [1] 에서 이 항목을 갖고 있다.
>. 이 솔루션은 정의됩니까 수 있도록 모든 가상 메서드입니다 순결케 않습니다. 단, [클라스스트로] /7 순수 가상 선언할 경우에도 소멸자 정의해야 합니다.
[1]: http://gcc.gnu.org/faq.html # 바타바레스
따라서 I& # 39, ve 생각 아웃해야 전송되었기 문제와 함께 나쁜거라 논리와 완전히 익숙하지 않고 automake / 오토 둘스 세계. 난 내 (Makefile.am), t, but i wasn& 템플리트를 올바른 파일을 추가 # 39 의 빌드 프로세스를 실제로 어떤 단계에 있는지 창조하 makefile 할 수 있다. 그래서, 내가 가진 모든 것을 전혀 모르고 있던 낡은 makefile 은 새로운 파일 컴파일하기를 연인으로써.
Mgcc FAQ 에 대응 및 링크 주셔서 감사합니다. 실제 이유는 이 문제를 피하기 위해 발생하고 있는 내아기마저도 읽도록 합니다.
다음 상황 또한 프터블 정의되지 않은 참조입니다 인해 발생할 수 있습니다. 그냥 이거라도 붙일래요:
클래스 A 가:
virtual void functionA(parameters)=0;
virtual void functionB(parameters);
클래스 B 포함:
C 클래스 포함: 지금 하고 있는 것인지, 클래스 C # 39 you& 먹어서나 파생합니다 정보기술 (it) 의 클래스 a
이제 프터블 클래스 C 에 대한 참조를 얻게 됩니다 컴파일하십시오 할 경우 정의되지 않은 오류로.
이유:
클래스 b 에서 제공하는 '펑크티오나' 순수 가상 및 그 정의는 다음과 같이 정의된다. '펑크티오노프 가상 아닌 순수 가상)' 로 정의되어 있으므로 그 자체가 정의 (definition) 에 Class A 클래스 정의를 제공하는 에서 찾으려고 합니다 확장하지만 B.
해결책:
여기에 대답을 많이 일어나고 있는 다양한 추측이 있다. # 39, ll i& 아래에 있는 이 오류가 발생하는 이유에 대해 최소한의 코드 및 것은 상당히 열거하십시오 재현합니다.
이바시오하프 *
#pragma once
class IBase {
public:
virtual void action() = 0;
};
#pragma once
#include "IBase.hpp"
class Derived : public IBase {
public:
Derived(int a);
void action() override;
};
#include "Derived.hpp"
Derived::Derived(int a) { }
void Derived::action() {}
#include <memory>
#include "Derived.hpp"
class MyClass {
public:
MyClass(std::shared_ptr<Derived> newInstance) : instance(newInstance) {
}
void doSomething() {
instance->action();
}
private:
std::shared_ptr<Derived> instance;
};
int main(int argc, char** argv) {
Derived myInstance(5);
MyClass c(std::make_shared<Derived>(myInstance));
c.doSomething();
return 0;
}
이렇게 mgcc 사용하여 이 컴파일하십시오 수 있습니다.
g++ -std=c++11 -o a.out myclass.cpp Derived.cpp
이제 '= 0' 의 이바시오하프트 제거하여 오류 재현 내가 afaq afnor 오류:
~/.../catkin_ws$ g++ -std=c++11 -o /tmp/m.out /tmp/myclass.cpp /tmp/Derived.cpp
/tmp/cclLscB9.o: In function `IBase::IBase(IBase const&)':
myclass.cpp:(.text._ZN5IBaseC2ERKS_[_ZN5IBaseC5ERKS_]+0x13): undefined reference to `vtable for IBase'
/tmp/cc8Smvhm.o: In function `IBase::IBase()':
Derived.cpp:(.text._ZN5IBaseC2Ev[_ZN5IBaseC5Ev]+0xf): undefined reference to `vtable for IBase'
/tmp/cc8Smvhm.o:(.rodata._ZTI7Derived[_ZTI7Derived]+0x10): undefined reference to `typeinfo for IBase'
collect2: error: ld returned 1 exit status
위 코드를 필요로 하지 않는 것을 볼 수 있는 가상 파일, 또는 다른 소멸자 구성자를 컴파일하십시오 성공하기 위한 추가 (단, 그들을 있어야 합니다.)
이 점을 이해할 수 있는 방법을 제시해 오류: 다음과 같습니다. 링커는 구성자를 이바제 찾고 있다. 이 대한 it 의 파생됨 구성자를 합니다. 그러나 이바제 첨부됩니다 참조할 것) 으로 오버라이드가 파생됨 메소드가 프터블 이바제 있다. 링커, 프터블 때 " 정의되지 않은 참조입니다 IBase" 위한 것이라고 말했습니다. 하지만, 이 프터블 참조입니다 can& # 39 는 기본적으로 파생됨 이바제 것을 찾을 수 없는 행동 이바제 컴파일됨 객체에는 여바바 최대. 즉, 클래스 선언은 그래서 이바제 구축 없이 있다. 즉, 수의 하지만 우리는 상태로 만들 수 있는 방법을 이바제 선언할 것을 제공하기 순수 가상 또는 정의할 수 있다.
실패할 경우 그 모든 디버그로 방법 중 하나는 이 프로그램을 구축할 수 있도록 최소한의 오류: 그리곤요 컴파일하십시오 않는 상태로 계속 변화하는 it gets 운영까지도. 그 사이 컴파일하기를 시작될 때, 계속 볼 수 없습니다.
클래스 집합 위에 있는 경우 컴파일하기를 조교하실 빌드 시스템을 사용하여 다음과 같은 줄을 사마크리스트스.t스트 마무리한 버들개지 합니다.
add_executable(myclass src/myclass.cpp src/Derived.cpp)
add_dependencies(myclass theseus_myclass_cpp)
target_link_libraries(myclass ${catkin_LIBRARIES})
첫 번째 줄은 실행가능파일 release. myclass 와 코드를 만들 수 있다고 기본적으로 우리가 원하는 파일을 inet6.0 구축하십시오 볼 수 있습니다. Main () 이 파일 중 하나를 가지고 있어야 합니다. # 39 지정할 수 있는 것을 볼 수 없는 파일을 어디든요 사마크리스트스.t스트리 오하프 don& 있습니다. 또한, don& # 39 라이브러리로 데이비드 스코프 지정할 수 없다.
그냥 이 오류가 있는 경우 다른 영역으로 실행했음 확인할 수 있습니다.
기본 클래스 a 순수 가상 함수를 정의할 수 있다.
virtual int foo(int x = 0);
그리고 하위 있었다.
int foo(int x) override;
오식 문제가 있는 것은 ',' 는 " = 0" 외부에서 있어야 합니다.
virtual int foo(int x) = 0;
따라서 이 경우, 당신은 아마 didn& you& # 39, re 스크롤하십시오 정지점은 다운되어도 # 39, t 는 - 이 답을 찾기 위해 무언가 확인할지.
Gnu c++컴파일러 결정을 내려야했다 프터블 '의 경우' 를 넣을 수 있는 가상 함수 정의를 전파하므로 개체의 여러 미완성 혹은 미개봉 작품 장치 (예를 들어 일부 개체가 가상 함수 정의를 사용할 수 있는 다른 파일을 다른 컨텍스트에서는 지크프 지크프 파일이므로 드릴링됩니다).
'를 넣을 수 있는 곳과 같은 컴파일러 선택했습니까 프터블' 의 첫 번째 선언된 가상 함수 정의됩니다.
이제 몇 가지 이유로 대한 정의를 제공하는 경우 분실 선언된 wt. 객체에는 하는 첫 번째 가상 함수 (또는 실수로 추가할 것을 컴파일됨 객체에는 dell. 링크뿐 단계) 이 오류를 얻을 수 있습니다.
이 특정 대해서만 유념하십시오 비호환성의 부작용, 가상 함수 너회가 won& 내려받습니다 전통표기 링커 오류가 없습니다 # 39 와 같은 함수, t foo .
그러나 금지커서 게시물로의 수 없습니다. 내가 겪고 있는 경우 상속, 즉, 두 번째 구글 타구는 인도하심이라만일 미달성 모든 가상 메소드 정의해야 합니다.
예:
virtual void fooBar() = 0;
랜스워스 자세한 내용은 https://stackoverflow.com/q/9406580/1592572 참조. 하지만 위에서 언급한 막 깨달은 it& # 39 에 이미 누군가가 헥 것이 도움이 됩니다.
이 솔루션은 놓쳤다 "정의" 이 에로남이네 확인을 할 수 있습니다. 아래 예제는 지켜보리니 피하기 위한 프터블 컴파일러와의 오류:
// In the CGameModule.h
class CGameModule
{
public:
CGameModule();
~CGameModule();
virtual void init();
};
// In the CGameModule.cpp
#include "CGameModule.h"
CGameModule::CGameModule()
{
}
CGameModule::~CGameModule()
{
}
void CGameModule::init() // Add the definition
{
}
이 때 최초로 검색 결과 가져다줄래요 그러하매 생각해봤죠 I&; d # 39 또 추가 확인 할 수 있습니다. 실제로 smartupdate 가상 함수 정의에 따라 구분된다. 내 경우, 내가 가진 이:
헤더 파일:
class A {
public:
virtual void foo() = 0;
};
class B : public A {
public:
void foo() override;
};
그리고 제 .cc 파일:
void foo() {
...
}
이 되어야 합니다
void B::foo() {
}
프터블 (때때로 " emitted",) 는 자동으로 생성됩니다. 의해 컴파일러와의. 낼 수 있는 모든 것을 컴파일러가 프터블 한 것이 아니라, 불필요한 오버킬 다형 번역 디바이스입니다 클래스 정의 일반적으로 볼 수 있습니다. 대체 ([사용하는 mgcc] (https://gcc.gnu.org/faq.html # 바타바레스), 아마 다른 사람에 의해) 는 하나의 변환 장치, 프터블 선택할 수 있는 단일 소스 파일을 저장할 수 있는 방법과 비슷한 고를거야 class& # 39. 정적 데이터 멤버를. 이 경우 모든 프로세스에 실패할 경우, 프터블 선택물을 좀 번역됨) 가 정의되지 않은 참조입니다. 특히, 그 메시지는 오류가 없는 선택해제합니다 업그레이드됨 알듯. 마찬가지로, 이 경우 선택 과정을 선택할 수 있으나, 그 번역 장치 객체 파일 제공하지 않은 링커, 다음 프터블 은 정의되지 않은 참조입니다. 이 경우 더 이상 선택해제합니다 죄송합니다. 오류 메시지가 될 수 있는 경우의 선정이 못했습니다. (답변자 힘입어 누가 그 가능성을 언급했다. 아마 그렇지 않은 경우에는 잊어버린 것이다.) 만약 우리가 사용하는 것이 합리적입니다 mgcc 선정 절차를 시작해 그동안 각 클래스 a (싱글) 전통을 소스 파일 하나만 있는 구축현 있다. 프터블 해당 소스 파일을 컴파일할 때 좋은 표시할 수 있을 것입니다. # 39 의 호출하십시오 let& 우리 목표다. 그러나 이 경우에도 사용할 수 없는 선택 과정을 요구사항뿐 전통인건지 뒤를 이었다. 그래서 찾는 대신에 구현에 대한 전체 클래스가 let& # 39 의 여바바 구현을 위해 특정 클래스의 멤버. 만약 전통인건지 가장 & ndash;; , 와 경우 해당 구성 요소가 실제로 구현됩니까 & ndash; 그런 다음 이 목표 달성. 멤버 mgcc 의해 선택된 첫 번째 인라인 비사양 않는 가상 함수 (그리고 다른 컴파일러에도 의해 잠재적으로) 는 순수 가상. 일부 경우, 그 전에 이미 다른 멤버 함수를 선언하는 관중의 구성자를 및 소멸자 소멸자 좋은 기회를 선택되었습니다. (재발했지 너희에게베풀어진 소멸자 할 수 있는 가상, 응?) 예외가 존재한다. # 39; d i& 때 가장 흔한 것으로 예외는 인라인 정의마다 소멸자 제공됩니다 언제 기본값입니다 소멸자 (기본 ',' = " " 사용하여,) 는 요청되었습니다. 다형 제공할 수 있는 것을 알 수 있는 모든 수업은 기민한 인라인 redefinitions) 는 가상 총괄하였습니다. # 39, t 선택물을 doesn& 원인이 되는 과정을 페일오버합니다? 그 이전 않니다 컴파일러에도. # 39 이 문제를 해결할 수 있지만, ve 검토완료 i& 이번 컴파일러에도 관련 버전 번호를 가지고 잘 모르겠습니다. 나는 할 수 있지만, 코드 s # 39 이 백업하도록 보았으매 시도하시겠습니까 it& 주변에 대한 불평을 컴파일러와의 또는 대기 중. 간단히 말해, 이 세 가지 주요 인해 " 정의되지 않은 참조입니다 vtable"; 오류:
Welcome back 백성중에 앞서 생략! )
virtual ~A() = default;
또는
virtual ~A() {}
? 그렇다면, 2 단계는 소멸자 변경하십시오 기능의 유형을 꽂으십시오 싶습니다. 첫째, 변화의 라인
virtual ~A();
둘째, 다음 줄을 동일팔레트에 소스 파일을 프로젝트에 일부인 (대부분 있는 파일을 클래스 구축, 존재하는 경우):
A::~A() {}
소멸자 (가상) 에 의해 생성되는 것이 아니라 컴파일러와의 인라인 비사양 수 있습니다. (언제든지 수정할 것을 더 충족하십시오 코드 포맷 등의 스타일을 추가에는 헤더입니다 의견을 함수를 정의할 수 있다.)
하지만 어느 누구도 그렇게 많은 여기에 대답을 적용 어떻게 내 문제가 있는 듯했다. 내가 경식도 다음과 같다.
class I {
virtual void Foo()=0;
};
또 다른 파일 (포함된 물론 컴파일 및 연결)
class C : public I{
void Foo() {
//bar
}
};
class C : public I{
void Foo();
};
C::Foo(){
//bar
}
저는 "windows xp 및 mingw 컴파일러와 함께 사용하여 qt 는 날 미친 이거 운전.
심지어 내가 어렸을 때 기본적으로 moc_xxx.cpp 생성된 추가되든지 빈
Q_OBJECT
삭제 기능을 하는 것, 모든 것을 너희에게 가상 명시성 doesn& # 39, 잊지 말아야 한다. 결국 내가 가진 것으로 드러나 행별로 시작했는데 제거 및
#ifdef something
주변에 절실해졌습니다. # 이프데프 경우에도 사실이 되었고 moc 파일이 생성되지 않았습니다.
그래서 모든 # 이프데프스 분리 문제가 해결되었습니다.
이거 발생합니까 Windows 및 VS 2013년 않았다.
실패할 경우, 모든 복제에서는 찾습니다. 제가 잘못 전달된 명시성 의해 또 다른 소멸자 읽기 및 초기 참조입니다 구성자를 전까진 참조입니다 It& 게시물로의. # 39 의 any 해결되지 않은 방법입니다. 제 경우에는 선언과 함께 사용하는 xml 로 재장착하여 생각해봤죠 했어요 const char 챨 &prs. 한 것은 문제가 있는 확장성표기언어 (xml), 하지만 난 이미 사용하여 만든 새로운 관계를 떠나 다른 중 1 위를 차지했다.