2016-04-12 16 views
0

Siehe Code unten. Es stimmt etwas nicht damit, weil der Linker sich beschweren kann, dass er die Memory Funktionen nicht finden kann, aber ich kann nicht herausfinden, warum.Linker kann die Funktionen eines Namespace nicht finden

MEMORY.H

#pragma once 
#include "includes.h" //it just includes other strandard headers. 

class MemoryUnit 
{ 
public: 
    MemoryUnit() {} 
    virtual int getValue() = 0; 
    virtual int getSize() = 0; 
    virtual void setValue(int) = 0; 
    virtual ~MemoryUnit() {}; 
}; 
class Byte : public MemoryUnit 
{ 
    int value; 
public: 
    static int size; 
    Byte(int byte) :value(byte) {}; 
    int getSize() { return size; } 
    int getValue() { return value; }; 
    void setValue(int byte) { value = byte; } 
    ~Byte() {}; 
}; 
namespace Memory 
{ 
    extern int size; 
    extern MemoryUnit** map; 
    void checkAddress(int address); 
    int read(int adress); 
    MemoryUnit* getOperation(int address); 
    void write(int adress, MemoryUnit* data); 
    void writeByte(int adress, int data); 
} 

memory.cpp

#include "includes.h" 
#include "memory.h" 
#include "simulator.h" // it contains only externed constants. 

namespace Memory 
{ 
    int size = 0; 
    MemoryUnit** map = NULL; 
    inline MemoryUnit* getOperation(int address) 
    { 
     return map[address]; 
    } 
    inline void checkAddress(int address) 
    { 
     if (address < 0 || address >= MAX_MEMORY_SIZE) 
      throw std::out_of_range("Invalid memory address."); 
    } 
    inline int read(int address) 
    { 
     checkAddress(address); 
     return map[address]->getValue(); 
    } 
    inline void write(int address, MemoryUnit* data) 
    { 
     checkAddress(address); 
     delete map[address]; 
     map[address] = data; 
    } 
    inline void writeByte(int address, int data) 
    { 
     checkAddress(address); 
     map[address]->setValue(data); 
    } 
} 

überall die Klasse/Namespace memory.h ist erklärt enthält memory.h. Ist hier etwas falsch in dem Code unten?

Edit: Ich bin mit Visual Studio 2015 Fehler habe ich, wenn das Projekt den Bau:

LNK1120 5 unresolved externals simulator.exe 
LNK2019 unresolved external symbol "void __cdecl Memory::writeByte(int,int)" referenced in function "void __cdecl ALU::setFlags(int)" alu.obj 
LNK2001 unresolved external symbol "void __cdecl Memory::writeByte(int,int)" cu.obj 
LNK2019 unresolved external symbol "class MemoryUnit * __cdecl Memory::getOperation(int)" referenced in function "void __cdecl CU::run(void)" cu.obj 
LNK2001 unresolved external symbol "void __cdecl Memory::writeByte(int,int)" helpers.obj 
LNK2019 unresolved external symbol "void __cdecl Memory::write(int,class MemoryUnit *)" referenced in function "void __cdecl readProgramCommands(void)" helpers.obj 
LNK2001 unresolved external symbol "public: virtual int __thiscall MemoryPointer::getValue(void)" helpers.obj 
LNK2001 unresolved external symbol "public: virtual int __thiscall IndirectMemoryPointer::getAddress(void)" helpers.obj 
LNK2001 unresolved external symbol "void __cdecl Memory::writeByte(int,int)" main.obj 

alu.h und alu.cpp für den ersten Fehler:

//alu.h 
#pragma once 
#include "includes.h" 
#include "operation.h" 
namespace ALU 
{ 
    int operation(Operation* op); 
    void setFlags(int result); 
} 
//alu.cpp 
#include "includes.h" 
#include "simulator.h" 
#include "alu.h" 
#include "memory.h" 
#include "operation.h" 
namespace ALU 
{ 
    int operation(Operation* operation) 
    { 
     // ... 
     setFlags(result); 
     return result; 
    } 
    inline void setFlags(int result) 
    { 
     Memory::writeByte(FLAG_Z, result == 0); 
     // ... 
    } 
} 
+0

Konnten Sie die genaue Fehlermeldung und die Linie zur Verfügung stellen, die den Fehler produziert? Sind Sie sicher, dass Sie auch memory.cpp kompiliert haben und dagegen verlinkt haben? – aybassiouny

+0

@aybassiouny Bearbeitete die Frage. Alle Dateien werden kompiliert, die Verknüpfung ist der Job des VS. – klenium

Antwort

1

Wenn Sie Inline-Funktionen oder Methoden verwenden, sollten ihre Definitionen für jede Quelleneinheit sichtbar sein, die sie verwendet. Sie haben Ihre Inline-Funktionen in Memory.cpp definiert, deshalb erhalten Sie einen "nicht aufgelösten" Linker-Fehler.

Ihr Problem beheben können Sie:

  1. Remove Inline-Modifikator und Funktionen Definitionen halten in Memory.cpp.

  2. Inline-Modifizierer beibehalten, aber Funktionsdefinitionen in Memory.h verschieben.

+0

Ich würde die 'Inline' behalten, weil diese so schnell sein sollten wie sie nur können. Aber ich habe nicht andere als Getter/Setter in Kopfzeilen geschrieben, ist es eine gute Idee, komplexere Funktionen innerhalb von Headern zu definieren? – klenium

+0

Wenn es zu komplex wäre, ignoriert der Compiler den Inline-Spezifizierer. Es wird also nicht schaden, wenn Sie es inline halten, wenn die Leistung der Hauptfaktor für Ihr Programm ist. – CodeFuller

2

Sie müssen setzen die Inline-Funktionsdefinition in Ihrer Header-Datei (beide müssen in jeder Übersetzungseinheit erscheinen, in der sie verwendet werden), Sie können Deklaration und Definition trennen, aber beide müssen in der Header-Datei sein. Sie müssen auch als Inline deklariert werden.

N4140 dcl.fct.spec 7.1.2.4

An inline function shall be defined in every translation unit in which it is odr-used and shall have exactly the same definition in every case (3.2). [ Note: A call to the inline function may be encountered before its definition appears in the translation unit. —end note ] If the definition of a function appears in a translation unit before its first declaration as inline, the program is ill-formed.