2017-05-10 94 views
0

我在讀一本關於C++的書。我仍然相當喜歡它,但我仍然試圖完成這些基本的事情。這一部分涉及繼承,目標是創建一個形狀類,然後用第一個二維形狀構建它,然後用二維形狀構建三維形狀。非模板類型的C++顯式實例化

到目前爲止,我已經能夠完成整個二維形狀。那裏的功能正常工作。現在我已經轉向了三維形狀,這就是我遇到的一個問題。

這本書說實現一個系統,允許長度,高度,併爲三維寬度可以是整數或浮動,所以我已經把一個模板來做到這一點。這是我認爲我遇到問題的地方。

我沒有複製過去的二維類到三維類,並嘗試從那裏完成它。然後我碰到了一些問題。

當我嘗試編譯時,出現兩個主要錯誤。

錯誤:「ThreeD」不是一個類模板 錯誤:非模板式「ThreeD」

我覺得是需要相關信息提交的最小的一塊的顯式實例。請記住,main.cpp,shape.h,shape.cpp,twod.h和twod.cpp按原樣工作,但我已經包含完整標題而不是完整的其他cpps。

任何幫助,你可以提供將是偉大的。

我已經把ThreeD.cpp放在頂端,因爲這是錯誤來自的地方。

我不認爲它是「爲什麼模板只能在頭文件中實現?」的副本因爲代碼可以在TwoD類中正常工作,而不是ThreeD類。

ThreeD.cpp

#include <iostream> 
#include <string> 
#include "shape.h" 
#include "TwoD.h" 

using namespace std; 

template class ThreeD<int>; 
template class ThreeD<float>; 


    template <class T> 
    ThreeD<T>::ThreeD (string oobj, int osides, T olength, T oheight, T owidth) 
     : TwoD<T>(oobj, osides, olength, oheight) 
    { 
     setObject(obj); 
     setSides(sides); 
     setLength(length); 
     setHeight(height); 
     setWidth(owidth); 
    } //End of TwoD constructor 

template <class T> 
int ThreeD<T>::getSides() { 
    return sides; 
} //End of function getSides 

的main.cpp

#include <iostream> 
#include "shape.h" 
#include "TwoD.h" 
#include "ThreeD.h" 

using namespace std; 

int main() { 


TwoD<float> triangle("Triangle", 3, 3, 3); 

ThreeD<float> cube("Cube", 6, 3, 3, 3); 
} 

Shape.h

#ifndef SHAPE_H 
#define SHAPE_H 

#include <string> 

using namespace std; 

//Implimenting template <class T> as a means to have the sides 
//variable become either a float or an int. 
template <class T> 
class Shape { 

public: 
    Shape(string, int, T); 
// void setObject(string); //Used to ensure constructor works 
    virtual void setObject(string) = 0; 
//Used setObject as virtual function since constructor uses it to 
//Make the object using the setObject function. 
    string getObject(); 
    int getSides(); 
    bool setSides(int); 
    float getLength(); 
    void setLength (T); 

    float getPerimeter(string, T); 
    float getArea (string, T); 

    void display(); 
private: 
    string object; 
    int sides; 
    T length; 
}; 

#endif 

Shape.cpp

#include <iostream> 
#include <string> 
#include "shape.h" 

using namespace std; 

//Telling the compiler template class of Shape which versions for T to 
//expect either int or float. 
template class Shape<int>; 
template class Shape<float>; 

//Constructor of Shape. Inputs shape, sides, and length. 
    template <class T> 
    Shape<T>::Shape (string shapes, int sides, T length){ 
     setObject(shapes); 
     setSides(sides); 
     setLength(length); 
    } //End of Shape constructor 

TwoD.h

#ifndef TWOD_H 
#define TWOD_H 

#include <string> 
#include "shape.h" 

using namespace std; 

//Implimenting template <class T> as a means to have the sides 
//variable become either a float or an int. 
template <class T> 
class TwoD : public Shape<T> 
{ 

public: 
    TwoD(std::string, int, T, T); 
    void setObject(string); //Used to ensure constructor works 
// virtual void setObject(string) = 0; 
//Used setObject as virtual function since constructor uses it to 
//Make the object using the setObject function. 
    string getObject(); 
    int getSides(); 
    bool setSides(int); 
    T getLength(); 
    void setLength (T); 
    T getHeight(); 
    void setHeight (T); 

    float getPerimeter(string, T, T); 
    float getArea (string, T, T); 

    void display(); 
private: 
    string object; 
    int sides; 
    T length; 
    T height; 
}; 

#endif 

TwoD.cpp

#include <iostream> 
#include <string> 
#include "shape.h" 
#include "TwoD.h" 

using namespace std; 

//Telling the compiler template class of TwoD which versions for T to 
//expect either int or float. 
template class TwoD<int>; 
template class TwoD<float>; 

//Constructor of TwoD. Inputs TwoD, sides, and length. 
    template <class T> 
    TwoD<T>::TwoD (string obj, int sides, T length, T height) 
     : Shape<T>(obj, sides, length) 
    { 
     setObject(obj); 
     setSides(sides); 
     setLength(length); 
     setHeight(height); 
    } //End of TwoD constructor 

ThreeD.h

#ifndef THREED_H 
#define THREED_H 

#include <string> 
#include "shape.h" 
#include "TwoD.h" 

using namespace std; 

//Implimenting template <class T> as a means to have the sides 
//variable become either a float or an int. 
template <class T> 
class ThreeD : public TwoD<T> 
{ 

public: 
    ThreeD(std::string, int, T, T, T); 
    void setObject(std::string); //Used to ensure constructor works 
// virtual void setObject(string) = 0; 
//Used setObject as virtual function since constructor uses it to 
//Make the object using the setObject function. 
    string getObject(); 
    int getSides(); 
    bool setSides(int); 
    T getLength(); 
    void setLength (T); 
    T getHeight(); 
    void setHeight (T); 

    T getWidth(); 
    void setWidth (T); 

    float getPerimeter(string, T, T, T); 
    float getArea (string, T, T, T); 

    void display(); 
private: 
    std::string object; 
    int sides; 
    T length; 
    T height; 
    T width; 
}; 

#endif 
+0

由於它在TwoD版本中工作,只是不是三維版本,我不認爲是這樣,但我是新的,可能是錯誤的。 – Greg

+1

完全不是這個重複...甚至讀了這個問題更接近? –

+0

我認爲M.M有正確的想法。 – Greg

回答

1

ThreeD.cpp你需要:

#include "ThreeD.h" 

沒有這個,行template class ThreeD<int>;品牌沒有感覺到編譯器,因爲ThreeD尚未被聲明。

+0

謝謝。這似乎是正確的答案。它允許我前進。對我這麼愚蠢的疏忽。感謝您指出,而其他人則試圖將其標記爲非相關帖子的副本。 – Greg

+0

@Greg是的,周圍有幾個人看到一個問題,並認爲這樣的話「對我來說太難了,或者我不會爲讀它而煩惱......更好地關閉它」 –