2014-02-24 133 views
2

我使用的是Xcode,我在下面提供了兩個標題:Spheres.h和Vector3.h,它們都被假設爲模板。 Vector3.h編譯沒有任何錯誤。類模板中的類模板

Spheres.h不進行編譯並返回此警告:"Expected ')'",並指出:

Sphere(const Vector3<T>& c,const float r); 
        ^

在裏面Sphere.h任何地方發生這種錯誤,我有一個Vector<T>。如果我刪除<T>的代碼可以編譯,我不明白。爲什麼?我想能夠使用相同的template<typename T>初始化Vector3<T>作爲Sphere<T>

請幫忙!

Sphere.h

#ifndef SPHERE 
#define SPHERE 

#include "Vector3.h" 

template <typename T> 
class Sphere 
{ 
public: 
    // Constructors 

    // Default 
    Sphere(); 

    // Copy 
    Sphere(const Sphere<T>& sphere); 

    Sphere(const Vector3<T>& c, const float r); 

    // Destructor 
    ~Sphere(); 

    // Get properties 

    const Vector3<T>& GetCenter() const; 
    const float& GetRadius() const; 

    // Set Properties 

    void SetCenter(const Vector3<T>& vector); 
    void SetRadius(const float& r); 

    // Methods 

    // Calculate sphere area: A = 4 * PI * r^2 
    const float GetArea() const; 

    // Calculate sphere volume: V = (4 * PI * r^3)/3 
    const float GetVolume() const; 

    // Return if given point of vector3 is within sphere 
    const bool PointIntersect(const Vector3<T>& point) const; 

    bool Overlap(const Sphere<T>& sphere); 

    // Tries to load data from a string 
    bool Load(std::string string) const; 

    // Operators 

    // Assignment operator 
    Sphere<T>& operator=(const Sphere<T>& sphere); 

    // Less than operator < 
    bool operator<(const Sphere<T>& s) const; 

    // Greater than operator > 
    bool operator>(const Sphere<T>& s) const; 

    // Less or equal operator <= 
    bool operator<=(const Sphere<T>& s) const; 

    // Greater or equal operator >= 
    bool operator>=(const Sphere<T>& s) const; 

    // Equal operator == 
    bool operator ==(const Sphere<T>& s) const; 

    // Not equal operator != 
    bool operator!=(const Sphere<T>& s) const; 

    // Print a sphere to console with cout 
    friend std::ostream& operator<<(std::ostream& out, const Sphere<T>& s); 

private: 
    T radius; 
    Vector3<T> center; 
}; 

// Implementation 

// Constructor 
// Default 
template<typename T> 
Sphere<T>::Sphere() 
{ 
    // Created empty sphere 
} 

// Copy 
template<typename T> 
Sphere<T>::Sphere(const Sphere<T>& sphere) 
{ 
    this->SetPosition(sphere.GetPosition()); 
    this->SetRadius(sphere.GetRadius()); 
    this->SetCenter(sphere.GetCenter()); 
} 

template<typename T> 
Sphere<T>::Sphere(const Vector3<T>& center,const float radius) 
{ 
    this->SetPosition(center); 
    this->radius = radius; 
} 


// Destructor 
template<typename T> 
Sphere<T>::~Sphere() 
{ 
    // Nothing to delete. 
} 

// Properties 

// Get 

template<typename T> 
const Vector3<T>& Sphere<T>::GetCenter() const 
{ 

    return center; 
} 

template<typename T> 
const float& Sphere<T>::GetRadius() const 
{ 
    return radius; 
} 

// Set 

template<typename T> 
void Sphere<T>::SetCenter(const Vector3<T>& vector) 
{ 
    this->SetPosition(vector); 
} 

template<typename T> 
void Sphere<T>::SetRadius(const float& r) 
{ 
    radius = r; 
} 

// Methods 


// Calculate sphere area: A = 4 * PI * r^2 
template<typename T> 
const float Sphere<T>::GetArea() const 
{ 
    float temp = 4 * pi * powf(this->GetRadius(), 2); 
    return temp; 
} 

// Calcutate sphere volume: V = (4 * PI * r^3)/3 
template<typename T> 
const float Sphere<T>::GetVolume() const 
{ 
    float temp = (4 * pi * powf(radius, 3))/3; 
    return temp; 
} 

// Return if given point of vector3 is within sphere 
template<typename T> 
const bool Sphere<T>::PointIntersect(const Vector3<T>& point) const 
{ 
    if (point.GetDistance(this->GetCenter(), point) >= this->radius) 
    { 
     return true; 
    } 
    return false; 
} 

template<typename T> 
bool Sphere<T>::Overlap(const Sphere<T>& sphere) 
{ 
    // Calculate the distance between the two spheres 
    float distance = Vector3::GetDistance(sphere.GetCenter(), this->GetCenter()); 

    // Calculate the length of both radiances 
    float radiusSum = sphere.radius + this->radius; 

    // if the length of radiance is greater than the distace -> there is a overlap 
    if (radiusSum > distance) 
     return true; 
    return false; 
} 

// Tries to load data from a string 
template<typename T> 
bool Sphere<T>::Load(std::string string) const 
{ 
    return false; 
} 

// Operators 

// Asignment operator 
template<typename T> 
Sphere& Sphere<T>::operator=(const Sphere<T>& sphere) 
{ 
    this->SetCenter(sphere.GetCenter()); 
    this->radius = sphere.radius; 
    return *this; 
} 

// Less than operator < 
template<typename T> 
bool Sphere<T>::operator<(const Sphere<T>& s) const 
{ 
    float v1 = this->GetVolume(); 
    float v2 = s.GetVolume(); 

    if (v1 < v2) 
     return true; 
    return false; 
} 

// Greater than operator > 
template<typename T> 
bool Sphere<T>::operator>(const Sphere<T>& s) const 
{ 
    float v1 = this->GetVolume(); 
    float v2 = s.GetVolume(); 

    if (v1 > v2) 
     return true; 
    return false; 
} 

// Less or equal operator <= 
template<typename T> 
bool Sphere<T>::operator<=(const Sphere<T>& s) const 
{ 
    float v1 = this->GetVolume(); 
    float v2 = s.GetVolume(); 

    if (v1 < v2) 
     return true; 
    if (v1 == v2) 
     return true; 
    return false; 
} 

// Greater or equal operator >= 
template<typename T> 
bool Sphere<T>::operator >=(const Sphere<T>& s) const 
{ 
    float v1 = this->GetVolume(); 
    float v2 = s.GetVolume(); 

    if (v1 > v2) 
     return true; 
    if (v1 == v2) 
     return true; 
    return false; 
} 

// Equal operator == 
template<typename T> 
bool Sphere<T>::operator ==(const Sphere<T>& s) const 
{ 
    float v1 = this->GetVolume(); 
    float v2 = s.GetVolume(); 

    if (v1 == v2) 
     return true; 
    return false; 
} 

// Not equal operator != 
template<typename T> 
bool Sphere<T>::operator !=(const Sphere<T>& s) const 
{ 
    float v1 = this->GetVolume(); 
    float v2 = s.GetVolume(); 

    if (v1 != v2) 
     return true; 
    return false; 
} 

// Print a sphere to console with cout 
template<typename T> 
std::ostream& operator<<(std::ostream& out, const Sphere<T>& s) 
{ 
    std::cout << "c:(" << s.GetCenter() << ") r:" << s.GetRadius(); 
    return out; 
} 

#endif 

Vector3.h

#ifndef VECTOR3 
#define VECTOR3 

// IO standard library 
#include <iostream> 

template<typename Type> 
class Vector3 
{ 
public: 
    // Constructor 
    Vector3(const Type& x, const Type& y, const Type& z); 

    // Copy constructor 
    Vector3(const Vector3<Type>& v); 

    // Destructor 
    ~Vector3(); 

    // Get properties 
    const Type& GetX() const; 
    const Type& GetY() const; 
    const Type& GetZ() const; 

    // Set properties 
    void SetX(const Type& value); 
    void SetY(const Type& value); 
    void SetZ(const Type& value); 

    // Methods 

    // Return length of the vector3<Type> 
    const float GetLength() const; 

    // Return the distance between two vector3<type> 
    const float GetDistance(const Vector3<Type>& v1, const Vector3<Type>& v2) const; 

    // Operators 

    // Assignment = 
    Vector3<Type>& operator=(const Vector3<Type>& v); 

    // Addition 
    Vector3<Type> operator+(const Vector3<Type>& v); 

    // Subtraction 
    Vector3<Type> operator-(const Vector3<Type>& v); 

    // Scalar product 
    float operator*(const Vector3<Type>& v); 

    // Multiplication 
    Vector3<Type> operator*(const float& s); 

    // Friend multiplication 
    friend Vector3<Type> operator*(const float& s, const Vector3<Type>& v); 

    // Cout: printing a vector3 to console 
    friend std::ostream& operator<<(std::ostream& out, const Vector3<Type>& v); 

private: 
    Type x; 
    Type y; 
    Type z; 
}; 

// Template implementation 

// Constructor 
template<typename Type> 
Vector3<Type>::Vector3(const Type& x, const Type& y, const Type& z) 
{ 
    this->SetX(x); 
    this->SetY(y); 
    this->SetZ(z); 
} 

// Copy constructor 
template<typename Type> 
Vector3<Type>::Vector3(const Vector3<Type>& v) 
{ 
    this->SetX(x); 
    this->SetY(y); 
    this->SetZ(z); 
} 

// Destructor 
template<typename Type> 
Vector3<Type>::~Vector3<Type>() 
{ 
    // Nothin to delete 
} 

// Get Properties 
template<typename Type> 
const Type& Vector3<Type>::GetX() const 
{ 
    return this->x; 
} 

template<typename Type> 
const Type& Vector3<Type>::GetY() const 
{ 
    return this->y; 
} 

template<typename Type> 
const Type& Vector3<Type>::GetZ() const 
{ 
    return this->z; 
} 

// Set properties 
template<typename Type> 
void Vector3<Type>::SetX(const Type& value) 
{ 
    this->x = value; 
} 

template<typename Type> 
void Vector3<Type>::SetY(const Type& value) 
{ 
    this->x = value; 
} 

template<typename Type> 
void Vector3<Type>::SetZ(const Type& value) 
{ 
    this->x = value; 
} 

// Methods 

// Return length of the vector3<Type> 
template<typename Type> 
const float Vector3<Type>::GetLength() const 
{ 
    float length = 0; 

    length = sqrtf(powf(x,2) + powf(y,2) + powf(z,2)); 
    return length; 
} 

// Return the distance between two vector3's 
template<typename Type> 
const float Vector3<Type>::GetDistance(const Vector3<Type>& v1, const Vector3<Type>& v2) const 
{ 
return sqrtf(powf((v2.x - v1.x), 2) + 
      powf((v2.y - v1.y), 2) + 
      powf((v2.z - v1.z), 2)); 
} 

// Operators 

// Assignment 
template<typename Type> 
Vector3<Type>& Vector3<Type>::operator=(const Vector3<Type>& v) 
{ 
    this->SetX(v.x); 
    this->SetY(v.y); 
    this->SetZ(v.z); 
    return *this; 
} 

// Addition 
template<typename Type> 
Vector3<Type> Vector3<Type>::operator+(const Vector3<Type>& v) 
{ 
    Type x, y, z; 

    x = this->x + v.x; 
    y = this->y + v.y; 
    z = this->z + v.z; 

    Vector3<Type> temp(x, y, z); 
    return temp; 
} 

// Subtraction 
template<typename Type> 
Vector3<Type> Vector3<Type>::operator-(const Vector3<Type>& v) 
{ 
    Type x,y,z; 

    x = this->x - v.x; 
    y = this->y - v.y; 
    z = this->z - v.z; 

    Vector3<Type> temp(x, y, z); 
    return temp; 
} 

// Scalar product 
template<typename Type> 
float Vector3<Type>::operator*(const Vector3<Type>& v) 
{ 
    float scalarP = (this->GetX() * v.x) + (this->GetY() * v.y) + (this->GetZ() * v.z); 

    return scalarP; 
} 

template<typename Type> 
Vector3<Type> Vector3<Type>::operator*(const float& s) 
{ 
    Vector3 temp(this->GetX() * s, this->GetY() * s, this->GetZ() * s); 
    return temp; 
} 

template<typename Type> 
Vector3<Type> operator*(const float& s, const Vector3<Type>& v) 
{ 
    Vector3<Type> temp(v.x * s, v.y * s, v.z * s); 
    return temp; 
} 


// Cout: printing a vector3 to console 
template<typename Type> 
std::ostream& operator<<(std::ostream& out, const Vector3<Type>& v) 
{ 
    std::cout << "x:" << v.x 
       << " y:" << v.y 
       << " z:" << v.z; 
    return out; 
} 

#endif 
+0

你在這裏使用的'Vector3'沒有模板參數:'const bool PointIntersect(const Vector3&point)const;'。否則,這似乎是唯一的直接錯誤。 – jrok

+0

[C++ typename和inner classes]的可能重複(http://stackoverflow.com/questions/3934692/c-typename-and-inner-classes) – kfsone

+3

@kfsone不是。你認爲他需要'typename'? – 0x499602D2

回答

1

下編譯海合會精細成才。除了修復顯而易見的語法錯誤之外,我還修改了構造函數以完全初始化對象。其他可能的解決方案是給Vector3一個默認的構造函數(這樣它可以有一個默認的初始值),或使center a Vector3<T>*

#ifndef SPHERE 
#define SPHERE 

#include "vector3.h" 

template <typename T> 
class Sphere 
{ 
public: 
    // Constructors 

    // Default 
    Sphere(); 

    // Copy 
    Sphere(const Sphere<T>& sphere); 

    Sphere(const Vector3<T>& c, const float r); 

    // Destructor 
    ~Sphere(); 

    // Get properties 

    const Vector3<T>& GetCenter() const; 
    const float& GetRadius() const; 

    // Set Properties 

    void SetCenter(const Vector3<T>& vector); 
    void SetRadius(const float& r); 

    // Methods 

    // Calculate sphere area: A = 4 * PI * r^2 
    const float GetArea() const; 

    // Calculate sphere volume: V = (4 * PI * r^3)/3 
    const float GetVolume() const; 

    // Return if given point of vector3 is within sphere 
    const bool PointIntersect(const Vector3<T>& point) const; 

    bool Overlap(const Sphere<T>& sphere); 

    // Tries to load data from a string 
    bool Load(std::string string) const; 

    // Operators 

    // Assignment operator 
    Sphere<T>& operator=(const Sphere<T>& sphere); 

    // Less than operator < 
    bool operator<(const Sphere<T>& s) const; 

    // Greater than operator > 
    bool operator>(const Sphere<T>& s) const; 

    // Less or equal operator <= 
    bool operator<=(const Sphere<T>& s) const; 

    // Greater or equal operator >= 
    bool operator>=(const Sphere<T>& s) const; 

    // Equal operator == 
    bool operator ==(const Sphere<T>& s) const; 

    // Not equal operator != 
    bool operator!=(const Sphere<T>& s) const; 

    // Print a sphere to console with cout 
    friend std::ostream& operator<<(std::ostream& out, const Sphere<T>& s); 

private: 
    T radius; 
    Vector3<T> center; 
}; 

// Implementation 

// Constructor 
// Default 
template<typename T> 
Sphere<T>::Sphere() 
    : radius(0), center(Vector3<T>(0,0,0)) 
{ 
    // Created empty sphere 
} 

// Copy 
template<typename T> 
Sphere<T>::Sphere(const Sphere<T>& sphere) 
    : radius(sphere.radius), center(sphere.center) 
{ 
} 

template<typename T> 
Sphere<T>::Sphere(const Vector3<T>& center, const float radius) 
    : radius(radius), center(center) 
{ 
} 


// Destructor 
template<typename T> 
Sphere<T>::~Sphere() 
{ 
    // Nothing to delete. 
} 

// Properties 

// Get 

template<typename T> 
const Vector3<T>& Sphere<T>::GetCenter() const 
{ 
    return center; 
} 

template<typename T> 
const float& Sphere<T>::GetRadius() const 
{ 
    return radius; 
} 

// Set 

template<typename T> 
void Sphere<T>::SetCenter(const Vector3<T>& vector) 
{ 
    this->SetPosition(vector); 
} 

template<typename T> 
void Sphere<T>::SetRadius(const float& r) 
{ 
    radius = r; 
} 

// Methods 

const float pi = 3.14; 
// Calculate sphere area: A = 4 * PI * r^2 
template<typename T> 
const float Sphere<T>::GetArea() const 
{ 
    float temp = 4 * pi * powf(this->GetRadius(), 2); 
    return temp; 
} 

// Calcutate sphere volume: V = (4 * PI * r^3)/3 
template<typename T> 
const float Sphere<T>::GetVolume() const 
{ 
    float temp = (4 * pi * powf(radius, 3))/3; 
    return temp; 
} 

// Return if given point of vector3 is within sphere 
template<typename T> 
const bool Sphere<T>::PointIntersect(const Vector3<T>& point) const 
{ 
    if (point.GetDistance(this->GetCenter(), point) >= this->radius) 
    { 
     return true; 
    } 
    return false; 
} 

template<typename T> 
bool Sphere<T>::Overlap(const Sphere<T>& sphere) 
{ 
    // Calculate the distance between the two spheres 
    float distance = Vector3<T>::GetDistance(sphere.GetCenter(), this->GetCenter()); 

    // Calculate the length of both radiances 
    float radiusSum = sphere.radius + this->radius; 

    // if the length of radiance is greater than the distace -> there is a overlap 
    if (radiusSum > distance) 
     return true; 
    return false; 
} 

// Tries to load data from a string 
template<typename T> 
bool Sphere<T>::Load(std::string string) const 
{ 
    return false; 
} 

// Operators 

// Asignment operator 
template<typename T> 
Sphere<T>& Sphere<T>::operator=(const Sphere<T>& sphere) 
{ 
    this->SetCenter(sphere.GetCenter()); 
    this->radius = sphere.radius; 
    return *this; 
} 

// Less than operator < 
template<typename T> 
bool Sphere<T>::operator<(const Sphere<T>& s) const 
{ 
    float v1 = this->GetVolume(); 
    float v2 = s.GetVolume(); 

    if (v1 < v2) 
     return true; 
    return false; 
} 

// Greater than operator > 
template<typename T> 
bool Sphere<T>::operator>(const Sphere<T>& s) const 
{ 
    float v1 = this->GetVolume(); 
    float v2 = s.GetVolume(); 

    if (v1 > v2) 
     return true; 
    return false; 
} 

// Less or equal operator <= 
template<typename T> 
bool Sphere<T>::operator<=(const Sphere<T>& s) const 
{ 
    float v1 = this->GetVolume(); 
    float v2 = s.GetVolume(); 

    if (v1 < v2) 
     return true; 
    if (v1 == v2) 
     return true; 
    return false; 
} 

// Greater or equal operator >= 
template<typename T> 
bool Sphere<T>::operator >=(const Sphere<T>& s) const 
{ 
    float v1 = this->GetVolume(); 
    float v2 = s.GetVolume(); 

    if (v1 > v2) 
     return true; 
    if (v1 == v2) 
     return true; 
    return false; 
} 

// Equal operator == 
template<typename T> 
bool Sphere<T>::operator ==(const Sphere<T>& s) const 
{ 
    float v1 = this->GetVolume(); 
    float v2 = s.GetVolume(); 

    if (v1 == v2) 
     return true; 
    return false; 
} 

// Not equal operator != 
template<typename T> 
bool Sphere<T>::operator !=(const Sphere<T>& s) const 
{ 
    float v1 = this->GetVolume(); 
    float v2 = s.GetVolume(); 

    if (v1 != v2) 
     return true; 
    return false; 
} 

// Print a sphere to console with cout 
template<typename T> 
std::ostream& operator<<(std::ostream& out, const Sphere<T>& s) 
{ 
    std::cout << "c:(" << s.GetCenter() << ") r:" << s.GetRadius(); 
    return out; 
} 

#endif 
+0

請解釋一下您修正的問題,以使其成爲適當形式的答案。 – kfsone

0

這是因爲你的Sphere類需要Vector3作爲模板類。喜歡這裏:

~Sphere(); 

// Get properties 

const Vector3<T>& GetCenter() const; 
const float& GetRadius() const; 

// Set Properties 

但是,當你提供SphereVector3<T>會造成這樣的Vector3<T><T>

+0

因此,如果我創建一個球體它會導致:Vector 。所以在我的代碼球體,Vector應該只宣佈Vector3以獲得矢量? – keyboardwarrior

+0

'Sphere ''將所有'T'替換爲'int',所以vector將是'const Vector3 &GetCenter()const;' – teivaz

+0

除了在github上有矢量數學的一些庫。此外,其中一個是我的。 – teivaz