2010-04-24 3 views
4

Я пытаюсь разработать код шаблона абстрактного дизайна для одного из моих проектов, как показано ниже. Но я не могу скомпилировать код. Предоставляя некоторые ошибки компиляции (например, «неразрешенные внешние символ "общественности: виртуальный пустота __thiscall Xsecs :: draw_lines (двойной, двойной)" (? draw_lines @ Xsecs @@ UAEXNN @ Z)») .. Может ли один помочь мне в этом ...Ошибка репликации внешнего символа (C++)

#include "stdafx.h" 
#include <iostream> 
#include <vector> 
#include "Xsecs.h" 
using namespace std; 
//Product class 

class Xsecs 
{ 
public: 
    virtual void draw_lines(double pt1, double pt2); 
    virtual void draw_curves(double pt1, double rad); 
}; 

class polyline: public Xsecs 
{ 
public: 
    virtual void draw_lines(double pt1,double pt2) 
    { 
     cout<<"draw_line in polygon"<<endl; 
    } 
    virtual void draw_curves(double pt1, double rad) 
    { 
     cout<<"Draw_curve in circle"<<endl; 
    } 
    /*void create_polygons() 
    { 
     cout<<"create_polygon_thru_draw_lines"<<endl; 
    }*/ 
}; 

class circle: public Xsecs 
{ 
public: 
    virtual void draw_lines(double pt1,double pt2) 
    { 
     cout<<"draw_line in polygon"<<endl; 
    } 
    virtual void draw_curves(double pt1, double rad) 
    { 
     cout<<"Draw_curve in circle"<<endl; 
    } 
    /*void create_circles() 
    { 
     cout<<"Create circle"<<endl; 
    }*/ 
}; 

//Factory class 
class Factory 
{ 
public: 
virtual polyline* create_polyline()=0; 
virtual circle* create_circle()=0; 
}; 

class Factory1: public Factory 
{ 
public: 
     polyline* create_polyline() 
{ 
    return new polyline(); 
} 
     circle* create_circle() 
{ 
    return new circle(); 
} 
}; 

class Factory2: public Factory 
{ 
public: 
     circle* create_circle() 
{ 
    return new circle(); 
} 
    polyline* create_polyline() 
{ 
    return new polyline(); 
} 
}; 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    Factory1 f1; 
    Factory * fp=&f1; 
    return 0; 
} 
+1

@Niranjan: Если у вас есть дополнительный вопрос, пожалуйста ** ** редактировать свой вопрос или задать новый. Не задавайте свой старый вопрос; это делает его очень запутанным, поскольку ответы больше не соответствуют этому вопросу. –

ответ

1

Во всех определениях класса вы забыли использовать общественное ключевое слово:

class ProductA1 : ProductA 

должен быть

class ProductA1 : public ProductA 

и так далее

2

Вы должны наследовать публично от A, как

class ProductA1 : public ProductA { 
... 

Без public ключевого слова, это соотношение частное наследование, который не является является разновидностью поэтому вы не можете просто отличить от ProductA1 до ProductA.

Скотт Мейерс объясняет это в Effective C++, Third Ed., пункт 39:

[...] компиляторы, когда дано иерархию, в которой класс Student публично наследуется от класса Person, неявно преобразовать студентов к лицам, когда тот для успешного вызова функции.

[...] первое правило, управляющее частным наследованием, которое вы только что видели в действии: в отличие от публичного наследования компиляторы обычно не преобразуют объект производного класса (например, Student) в объект базового класса (например, как Person), если отношение наследования между классами является приватным. [...] Второе правило состоит в том, что члены, унаследованные от частного базового класса, становятся частными членами производного класса, даже если они защищены или публичны в базовом классе.

Частное наследственное средство -внедрено-в-условиях-. Если вы сделаете класс D частным образом наследуемым от класса B, вы это сделаете, потому что вы заинтересованы в использовании некоторых функций, доступных в классе B, а не потому, что существует какая-либо концептуальная связь между объектами типов B и D. Таким образом, частное наследование является чисто техникой реализации.

Update для 2-й вариант поста: если вы хотите, чисто виртуальные функции, вы должны объявить их так:

virtual void draw_lines(double pt1, double pt2) = 0; 
virtual void draw_curves(double pt1, double rad) = 0; 

В противном случае компоновщик будет не хватать их определение.

+0

спасибо за ответ. Я написал код аналогичным образом, но он дает некоторую другую ошибку компиляции .. теперь новый код добавлен в вышеуказанный вопрос. Не могли бы вы помочь мне. – Red

+0

@Niranjan, см. мое обновление. –

-1

изменить «класс» в «STRUCT» это сделать открытое наследование по умолчанию, а не частной

6

Я полагаю, вы пытались создать виртуальный базовый класс.Вам нужно добавить «= 0» до конца draw_lines и draw_curves методов в классе Xsecs

class Xsecs 
{ 
public: 
    virtual void draw_lines(double pt1, double pt2) = 0; 
    virtual void draw_curves(double pt1, double rad) = 0; 
}; 

компилятора жалуясь, как вы не какая-либо реализация методов в вопросе.

1

Вам необходимо либо добавить реализацию для Xsecs :: draw_lines/Xsecs :: draw_curves, либо определить их как чистый виртуальный, добавив «= 0» к их определению.

class Xsecs 
{ 
public: 
    virtual void draw_lines(double pt1, double pt2) 
    { 
     // Do something 
    } 
    virtual void draw_curves(double pt1, double rad) 
    { 
     // Do something 
    } 
}; 

Или ...

class Xsecs 
{ 
public: 
    virtual void draw_lines(double pt1, double pt2) = 0; 
    virtual void draw_curves(double pt1, double rad) = 0; 
};