0

I created a templated data class (CAnyData, please see its header file copy for your reference), with which I declared some variables in my another class (CConstantDataBlock, please see its header file copy for your reference). As you may see, the latter one is nearly an empty class. But when I compiled my project, the VS2008 compiler thowed the following linking errors. Would please help me figure out what's wrong with my CConstantDataBlock and/or CAnyData?

1>------ Build started: Project: Tips, Configuration: Debug Win32 ------
1>Compiling...
1>ConstantDataBlock.cpp
1>Linking...
1>   Creating library F:\Tips\Debug\Tips.lib and object F:\Tips\Debug\Tips.exp
1>ConstantDataBlock.obj : error LNK2019: unresolved external symbol "public: __thiscall CAnyData<double>::~CAnyData<double>(void)" (??1?$CAnyData@N@@QAE@XZ) referenced in function __unwindfunclet$??0CConstantDataBlock@@QAE@XZ$0
1>ConstantDataBlock.obj : error LNK2019: unresolved external symbol "public: __thiscall CAnyData<int>::~CAnyData<int>(void)" (??1?$CAnyData@H@@QAE@XZ) referenced in function __unwindfunclet$??0CConstantDataBlock@@QAE@XZ$0
1>ConstantDataBlock.obj : error LNK2019: unresolved external symbol "public: __thiscall CAnyData<double>::CAnyData<double>(void)" (??0?$CAnyData@N@@QAE@XZ) referenced in function "public: __thiscall CConstantDataBlock::CConstantDataBlock(void)" (??0CConstantDataBlock@@QAE@XZ)
1>ConstantDataBlock.obj : error LNK2019: unresolved external symbol "public: __thiscall CAnyData<int>::CAnyData<int>(void)" (??0?$CAnyData@H@@QAE@XZ) referenced in function "public: __thiscall CConstantDataBlock::CConstantDataBlock(void)" (??0CConstantDataBlock@@QAE@XZ)
1>F:\Tips\Debug\Tips.exe : fatal error LNK1120: 4 unresolved externals
1>Build log was saved at "file://f:\Tips\Tips\Debug\BuildLog.htm"
1>Tips - 5 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

#pragma once

#include <string>

using namespace std;

template <class T>
class CAnyData
{
public:
    CAnyData(void);
    CAnyData(int nWordNumber, string sContents, T Type, int nWidth, int nPrecision);
    ~CAnyData(void);

// Operators
    CAnyData( const CAnyData& rhs );
    const CAnyData& operator = (const CAnyData& rhs);

    // Must define less than relative to name objects.
    bool operator<( const CAnyData& AnyData ) const;

    // Compares profile's of two objects which represent CAnyData
    inline bool operator ==(const CAnyData& rhs) const;

// Get properties  
    inline int WordNumber() const { return m_nWordNumber; }
    inline const string& Contents() const { return m_sContents; }
    inline const T& DataType() const { return m_Type; }
    inline int Width() const { return m_nWidth; }
    inline int Precision() const { return m_nPrecision; }

// Set properties
    void WordNumber(int nWordNumber) const { m_nWordNumber = nWordNumber; }
    void Contents(string sContents) const { m_sContents = sContents; }
    void DataType(T Type) const { m_Type = Type; }
    void Width(int nWidth) const { m_nWidth = nWidth; }
    void Precision(int nPrecision) const { m_nPrecision = nPrecision; }

protected:
    void Init(void);

protected:
    int m_nWordNumber;
    string m_sContents;
    T m_Type;
    int m_nWidth;
    int m_nPrecision;
};

#pragma once

#include "AnyData.h"

// Constants block
// This block consists of 64 words to be filled with useful constants.

class CConstantDataBlock
{
public:
    CConstantDataBlock(void);
    ~CConstantDataBlock(void);

protected:
    CAnyData<int>    m_nEarthEquatorialRadius;
    CAnyData<int>    m_nNominalSatelliteHeight;
    CAnyData<double> m_dEarthCircumference;
    CAnyData<double> m_dEarthInverseFlattening;
};
Bo Persson
  • 90,663
  • 31
  • 146
  • 203
GoldenLee
  • 737
  • 2
  • 13
  • 28

1 Answers1

1

It seems that you do not have definitions for several of the methods of CAnyData, including the default constructor and the destructor. When you use these in your CConstantDataBlock-class, the constructor and destructor are required though.

Since CAnyData is a class-template, all definitions should be written directly into the header-file (just as you have done with all the getters and setters).

Community
  • 1
  • 1
Björn Pollex
  • 75,346
  • 28
  • 201
  • 283
  • Dear Space_C0wb0y I implementd all the Get/Set methods appeared in attached header file. I didn't post the corresponding cpp file. – GoldenLee May 29 '11 at 09:03
  • @GoldenLee: The separation into headers and source-files does not work with class templates. See the link I provided in my answer. The simplest solution is to implement all methods directly in the header-file. – Björn Pollex May 29 '11 at 09:06
  • I noticed that many programmers really split them into two parts implementation, namly header (.h) and implementation (.cpp). I don't know why. It depends on compiler and linker version, right? Anyway, I'll take your suggestion, and merge the two. Thank you! – GoldenLee May 29 '11 at 09:09
  • @Golden Nope, many programmers don't do that, and its not compiler or linker dependent. –  May 29 '11 at 09:11
  • Dear Space_C0wb0y and Neil Butterworth, Thank you! I'd never split the templated data structure or class again! But I'd ever read an ebook titled "Data Structures and Algorithms with Object-Oriented Design Patterns in C++" on the web site http://www.brpreiss.com/books/opus4/html/page81.html. If you have time, you could vist it. – GoldenLee May 29 '11 at 09:33
  • The sample code in "Data Structures and Algorithms with Object-Oriented Design Patterns in C++" really lead a wrong way for c++ templated programming. Altough it's really a good book! – GoldenLee May 29 '11 at 09:37
  • @Golden: If you want to know some really good books on C++, check out [this list](http://stackoverflow.com/questions/388242/). – Björn Pollex May 29 '11 at 09:42