I am trying to develop abstract design pattern code for one of my project as below.. But, I am not able to compile the code ..giving some compile errors(like "unresolved external symbol "public: virtual void __thiscall Xsecs::draw_lines(double,double)" (?draw_lines#Xsecs##UAEXNN#Z)" ).. Can any one please help me out in this...
#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;
}
I presume you were attempting to create a virtual base class. You need to add '= 0' to the end of the draw_lines and draw_curves methods in the class Xsecs
class Xsecs
{
public:
virtual void draw_lines(double pt1, double pt2) = 0;
virtual void draw_curves(double pt1, double rad) = 0;
};
the compiler is complaining as you haven't any implementation for the methods in question.
You should inherit publicly from A, like
class ProductA1 : public ProductA {
...
Without the public keyword, this relationship is private inheritance, which is not an is-a relationship, therefore you can't simply cast from ProductA1 to ProductA.
Scott Meyers explains this in Effective C++, Third Ed., Item 39:
[...] compilers, when given a hierarchy in which a class Student publicly inherits from a class Person, implicitly convert Students to Persons when that is necessary for a function call to succeed.
[...] the first rule governing private inheritance you've just seen in action: in contrast to public inheritance, compilers will generally not convert a derived class object (such as Student) into a base class object (such as Person) if the inheritance relationship between the classes is private. [...] The second rule is that members inherited from a private base class become private members of the derived class, even if they were protected or public in the base class.
Private inheritance means is-implemented-in-terms-of. If you make a class D privately inherit from a class B, you do so because you are interested in taking advantage of some of the features available in class B, not because there is any conceptual relationship between objects of types B and D. As such, private inheritance is purely an implementation technique.
Update for the 2nd version of the post: if you want pure virtual functions, you should declare them so:
virtual void draw_lines(double pt1, double pt2) = 0;
virtual void draw_curves(double pt1, double rad) = 0;
Otherwise the linker will miss their definition.
In all your class definitions you forgot to use the public keyword :
class ProductA1 : ProductA
should be
class ProductA1 : public ProductA
and so on
You either need to add an implementation for Xsecs::draw_lines / Xsecs::draw_curves, or define them as pure virtual, by appending "= 0" to their definition.
class Xsecs
{
public:
virtual void draw_lines(double pt1, double pt2)
{
// Do something
}
virtual void draw_curves(double pt1, double rad)
{
// Do something
}
};
Or...
class Xsecs
{
public:
virtual void draw_lines(double pt1, double pt2) = 0;
virtual void draw_curves(double pt1, double rad) = 0;
};
change "class" to "struct" this make the default public inheritance rather than private
Related
I am trying to practice OOP in C++ but I am running into an issue regarding overriding of functions. In my Shape2D and Shape3D classes, I have virtual functions which I redefine in the Square and Sphere classes (ShowArea() and ShowVolume() respectively). However, when I redefine the function and try to run the main, it outputs the errors:
Shapes.cpp:88:14: error: 'void Square::ShowArea() const' marked 'override', but does not override
void ShowArea() const override{
Shapes.cpp:353:14: error: 'void Sphere::ShowVolume() const' marked 'override', but does not override
void ShowVolume() const override {
Below is a snippet of relevant code from both the Shape2D, Square, Shape3D, and Sphere classes.
class Shape2D : virtual public Shape {
public:
virtual float Area() const = 0;
void ShowArea() const;
virtual string GetName2D() const = 0;
}
class Square: public Shape2D {
private:
float squareLen;
public:
// Constructors
Square() {
squareLen = 0;
}
Square(float len) {
squareLen = len;
}
string GetName2D() const override {
string res;
return res;
}
// Returns the area of the shape
float Area() const override {
return (squareLen * squareLen);
}
void ShowArea() const override{
cout << "Square Area: " << endl;
}
}
class Shape3D : virtual public Shape {
public:
virtual float Volume() const = 0;
void ShowVolume() const;
virtual string GetName3D() const = 0;
}
class Sphere: public Shape3D {
private:
Circle* SphereBase;
public:
Sphere() {
SphereBase = new Circle();
}
Sphere(float radius) {
SphereBase = new Circle(radius);
}
float Volume() const {
return (1.3333 * pi * pow(SphereBase->GetRadius(), 3));
}
void ShowVolume() const override {
}
Why is this the case when I am redefining the function in the subclasses and the function is virtual in its original definition? It does not work for any of my shapes (I have 6 shapes but only included 2 in this post) so I dont think its a typo and its crashes across both 2D and 3D shapes so its not an issue with those specific classes.
The function ShowArea declared in the class Shape2D
void ShowArea() const;
is not a virtual function. So this declaration in the derived class Square
void ShowArea() const override{
cout << "Square Area: " << endl;
}
is incorrect.
Also the function ShowVolume declared in the class Shape3D is not a virtual function
void ShowVolume() const;
It may not be overridden in a derived class.
You need to declare the functions to be virtual in base classes that they could be overridden.
The problem is that currently the member functions showArea and showVolume are not virtual member functions and we can use override keyword only when overriding a virtual member function.
To solve this you need to make showArea and showVolume virtual member functions by adding the keyword virtual as shown below:
class Shape2D : virtual public Shape {
public:
//--vvvvvvv------------------------->virtual added here
virtual void ShowArea() const;
//other code here
};
class Shape3D : virtual public Shape {
public:
//------vvvvvvv------------------------------>virtual added here
virtual void ShowVolume() const;
//other code here
};
//other code here
I'm wondering if the following is possible. I wanted my derived class dA to change func() to be pure virtual so that any classes derived from dA must implement func().
Code similar to below compiles without complaint under MSVC even though ddA does not implement func().
The compiler does complain about the below code (see comments). So my question now becomes: is this a standards-compliant way to achieve what I want?
class A {
public:
virtual void func() { /* Some base implementation. */ }
}
class dA : public A {
public:
void func() override = 0; // Is this valid?
}
class ddA : public dA {
}
Pure virtual function should be declared in parent class. Consider the code below:
'''
class Shape {
public:
Shape(int init_x, int init_y) : x(init_x), y(init_y) {}
virtual void scale(int s) = 0;
virtual void print() = 0;
protected:
int x;
int y;
};
These functions should be implemented in children:
class Rect : public Shape {
public:
Rect(int init_x, int init_y, int w, int h);
virtual void scale(int s) { //implementation }
virtual void print() { //implementation }
private:
int width;
int height;
};
However you don't have to implement virtual functions in subclasses since it had been implemented in super class:
Pure virtual function make your class abstract so you can't use its instances.
Please refer the following example.
using namespace std;
//Base interface
class IBase
{
public:
virtual void BaseMethod1() = 0;
virtual void BaseMethod2() = 0;
};
class IEntity1 : public IBase
{
public:
virtual void Entity1Method1() = 0;
virtual void Entity1Method2() = 0;
};
class Entity1 : public IEntity1
{
public:
Entity();
//IBaseMethods
void BaseMethod1();
void BaseMethod2();
//IEntityMethods
void Entity1Method1();
void Entity1Method2();
//EntityMethods
void Method1();
void Method2();
};
In the above example, for all other entities deriving from IBase needs to implement BaseMethod1() and BaseMethod2().Because of which lots of code duplication is happening? Is there anyway where we can avoid redundant implementation of IBase methods in entities deriving from it?
You can use virtual inheritance in combination with a default base implementation class to encapsulate your default base behavior, and have it be only inherited by the concrete classes you want, like follows:
using namespace std;
//Base interface
class IBase
{
public:
virtual void BaseMethod1() = 0;
virtual void BaseMethod2() = 0;
};
class IEntity1 : virtual public IBase
{
public:
virtual void Entity1Method1() = 0;
virtual void Entity1Method2() = 0;
};
class BaseImpl : virtual public IBase
{
public:
virtual void BaseMethod1()
{
...
}
virtual void BaseMethod2()
{
...
}
}
class Entity1 : public IEntity1, public BaseImpl
{
public:
Entity1();
//IEntityMethods
void Entity1Method1();
void Entity1Method2();
//EntityMethods
void Method1();
void Method2();
};
There is, however, a runtime cost associated with virtual inheritance. Multiple inheritance also comes with some structural issues, e.g. base class construction.
You can even have some fun with template classes to make your class composition more modular:
template<typename TEntity, typename TBaseImpl>
class ConcreteEntity: public TEntity, public TBaseImpl
{
public:
ConcreteEntity() {}
};
class ConreteEntity1 : public ConcreteEntity<IEntity1, BaseImpl>
{
public:
ConreteEntity1();
//IEntityMethods
void Entity1Method1();
void Entity1Method2();
//ConreteEntity1 Methods
void Method1();
void Method2();
};
You could make a function that is called in BaseMethod1() implementations that are the same.
Something like this:
void BaseMethod1_common();
class Entity1 : public IEntity1
{
public:
Entity();
//IBaseMethods
void BaseMethod1() { BaseMethod1_common(); }
void BaseMethod2();
//IEntityMethods
void Entity1Method1();
void Entity1Method2();
//EntityMethods
void Method1();
void Method2();
};
First of all IBase deserves a virtual destructor.
Declare it pure virtual and define IBase:BaseMethod1() and
IBase::BaseMethod1().
If your intention is to hide implementation, then the only option would be to release the code as a library and then share only the header file among the other developers.
Implementing a global function, or using multiple inheritance as suggested still mean that your implementation is exposed.
However, if the intent is to reduce coupling among the various classes, there's another option :
Create a class that has the actual shared implementation, and then another class which will be an interface to it.
This interface class will then be the base class for other derived entities.
Example code is shown below :
//First Header and Cpp file
class Base_private
{
public:
BaseImpl(arguments);
~BaseImpl();
void BaseMethod1() {
//Implementation
}
void BaseMethod2() {
//Implementation
}
};
//Second Header and Cpp file
class BaseInterface
{
public:
BaseInterface(arguments);
~BaseInterface();
void BaseMethod1() {
m_pBase->BaseMethod1();
}
void BaseMethod2() {
m_pBase->BaseMethod2();
}
private:
Base_private* m_pBase;
};
class Entity : public BaseInterface
{
public:
Entity(arguments);
~Entity();
void Method1();
void Method2();
};
I'm not happy with the question title, but I couldn't describe it well. I'm putting implementation in the class declarations for sake of brevity.
I have a class like this:
class VisibleObject {
public:
void draw(sf::RenderWindow& rw) {
rw.draw(*shape.get());
}
virtual void setSize(sf::Vector2f) = 0;
protected:
std::shared_ptr<sf::Shape> shape;
}
sf::Shape is an abstract class. Then I have a derived class like so:
class Brick : VisibleObject {
Brick() {
shape.reset(new sf::RectangleShape());
}
void setSize(sf::Vector2f newSize) {
std::dynamic_pointer_cast<sf::RectangleShape>(shapes).get()->setSize(newSize);
}
}
sf::RectangleShape() is a concrete class that inherits from sf::Shape and setSize() is defined for it, not sf::Shape, which is why I need to cast.
Of course, I need to do some error handling, in the case that the dynamic cast fails and returns an empty shared_ptr.
I'm doing this because I wanted to be able to define the draw method just once, since in this simple game, every object will draw their member this way. Originally I left the shape out of the base class, and e.g. Brick would just have its own private sf::RectangleShape that could get instantiated on the stack; which was clean, but then the draw method had to be re-written for each object type.
This works, but is uglier to work with and introduces heap allocation. I also have shared_ptr overhead (I would have used unique_ptr, but I needed dynamic casting).
Is this the most appropriate way of doing what I'm trying to do?
It might be preferable to keep the interface an interface, and not start mandating implementation details. So just have an empty base class like so:
class VisibleObject
{
public:
~VisibleObject() {}
virtual void draw(sf::RenderWindow & window) = 0;
virtual void setSize(sf::Vector2f const & size) = 0;
};
You can stick the shape storage into the concrete class that implements this interface.
Moreover, Shape should provide a virtual resize method:
class Shape
{
public:
virtual ~Shape() {}
virtual void resize(sf::Vector2f const & size) = 0;
};
Now you can make, say, a VisibleShapeObject as an intermediate base class:
class VisibleShapeObject : public VisibleObject
{
public:
virtual void draw(sf::RenderWindow & window) override final
{
window.draw(*shape_);
}
virtual void setSize(sf::Vector2f const & size) override final
{
shape_->resize(size);
}
protected:
std::shared_ptr<Shape> shape_; // or unique_ptr<Shape>
};
Instead of mandating storage in std::shared_ptr<sf::Shape>, why not simply introduce a means of retrieving an sf::Shape& from the concrete class?
class VisibleObject {
virtual sf::Shape& getShape() = 0;
public:
void draw(sf::RenderWindow& rw) {
rw.draw(getShape());
}
virtual void setSize(sf::Vector2f) = 0;
};
class Brick : VisibleObject {
sf::RectangleShape shape;
sf::Shape& getShape() override { return shape; }
public:
void setSize(sf::Vector2f newSize) override {
shape.setSize(newSize);
}
};
It seems ridiculous to store via a pointer to base, introducing indirections and downcasts and reference count overhead, when you could just store a plain old member. In fact, if I'm understanding the problem correctly, you could probably use a template to generate concrete classes and avoid a lot of boilerplate:
class VisibleObject {
public:
virtual ~VisibleObject() {}
virtual void draw(sf::RenderWindow&) = 0;
virtual void setSize(sf::Vector2f) = 0;
};
template <typename Shape>
class VisibleConcreteObject : public VisibleObject {
Shape shape;
public:
void draw(sf::RenderWindow& rw) override /* final? */ {
rw.draw(shape);
}
void setSize(sf::Vector2f newSize) override /* final? */ {
shape.setSize(newSize);
}
};
typedef VisibleConcreteObject<sf::RectangleShape> Brick;
You haven't shared everything you are trying to do, but this it one way:
template<ShapeT>
class VisibleObject {
public:
void draw(sf::RenderWindow& rw) {
rw.draw(*shape.get());
}
virtual void setSize(sf::Vector2f) = 0;
protected:
std::shared_ptr<ShapeT> shape;
void reset(ShapeT* shape) {
this->shape = shape;
}
}
class Brick : VisibleObject<sf::RectangleShape> {
Brick() {
shape.reset(new sf::RectangleShape());
}
void setSize(sf::Vector2f newSize) {
shape->setSize(newSize);
}
}
There may be reasons why this doesn't work for you, but without more insight, I couldn't guess at what.
Let's say we have a derived class from an abstract base class. A pointer to the abstract base class is declared in the main and allocated to the derived class through "new". How do you access the member functions of the derived class from a pointer to the base class (not from an object of the derived class)?
Example:
#include <iostream>
using namespace std;
class clsStudent
{
public:
virtual void display() = 0;// {cout<<"Student\n";}
};
class clsInternational : public clsStudent
{
public:
void display(){cout<<"International\n";}
void passportNo(){cout<<"Pass\n";}
};
class local : public clsStudent
{
public:
void display(){cout<<"International\n";}
void icNo(){cout<<"IC\n";}
};
int main()
{
clsStudent * s = new clsInternational;
clsStudent * s2 = new local;
s->display();
s->passportNo(); //This won't work
return 0;
}
Cheeky answer: don't. I mean, if you really need to, the answer to your technical question is the dynamic_cast operation in C++, in order to a conduct a "downcast" (cast from base to derived class).
But stepping back, this is a reasonable use case for a virtual function. Ask yourself, what is the common meaning I want to access?
In this case, we want all students to have an identifying number.
Working source code: http://ideone.com/5E9d5I
class clsStudent
{
public:
virtual void display() = 0;// {cout<<"Student\n";}
virtual void identifyingNumber() = 0;
};
class clsInternational : public clsStudent
{
public:
void display(){cout<<"International\n";}
void identifyingNumber(){cout<<"Pass\n";}
};
class local : public clsStudent
{
public:
void display(){cout<<"Local\n";}
void identifyingNumber(){cout<<"IC\n";}
};
int main()
{
clsStudent * s = new clsInternational;
clsStudent * s2 = new local;
s->display();
s->identifyingNumber();
s2->display();
s2->identifyingNumber();
return 0;
}