Calling a function which belongs to another class - c++

I'm just wondering if there is a way to call a function from another class which is not a derived class.
For example...
If I have class Square which has a function colour, if I have another class Triangle, totally unrealated to Square, can I somehow call the colour funciton of Square on a Triangle object?
I'm wondering if friend can be used here, but from what I have read, it can't, unless I've misunderstood what I've read.
What is the best way to implement this without creating an inheritance relationship?

If what your seeking to do is something like this:
Square s;
Triangle t;
t.colour(); // invoke Square::colour() on a Triangle
I'm sorry but you can't, unless you declare a function in Triangle which simply mimics what Square::colour does.
A wise option if you really need that function to be shared is to declare it as a standalone templated function like this:
template<typename Shape>
void colour(Shape s){
//Do stuff
}
then in order to allow this access to the inner guts of Triangle and Square, make void colour<Triangle>() and void colour<Square>() friends of the appropriate classes.

The answer is no, your request is not possible. The colour method is encapsulated within square and will not apply to an unrelated object of a difference class. Either inherit (from shape - I know you said no inheritance), or re-implement the colour method for square as well.

No, sorry to bum you out. But i would recommend using a base class 'shape', and derive shapes from this class.
class Abc //Abstract base class
{
public:
virtual ~Abc(); //destructor
virtual double Color();
virtual double Area() const = 0; //pure virtual, MUST be overridden
private:
//specific variables that apply to all shapes
};
class Square : public Abc //derived class from pure virtual class
{
public:
Square();
virtual double Color();
virtual double Area() const; //redefine color here
~Square(){}
private:
//square vars here
};

Related

abstract class A inherited by class C "through" an "intermediary" class B. How to declare the virtual fuctions?

Let's say I have
struct Transformable {
virtual void mirror()=0;
}
class Shape: public Transformable {
Position position;
Color color;
public:
virtual void draw()=0; // 0. <-this, or
virtual void draw(); // I. <-this, or
void draw(); // II. <-this, or maybe
// III. <-this?
}
class Circle {
double radius;
public:
void mirror();
}
(Where Transformable is the abstract class A, Shape is the "intermediary" class B, and Circle is C.)
Which should I use from the cases I-III (noted in //comments above)?
It doesn't make sense for Shape to have a function mirror(), so I would not want to write any code there, choosing option 0 over III.
If I would want to write code, I'd choose I over II.
If I'm right, why? If not, why?
Edit: I need class Shape for a heterogeneous collection, and I made a class Transformable to have transform functions separate from everything. Also I chose to have it go through Shape because this way I don't have to type
AnyShape: public Transformable, public Shape
only
AnyShape: public Shape
Usually, the virtual keyword is only used in the base class. You can omit it in all derived classes and the method will nevertheless be virtual. You can still use it, but it doesn't add much except maybe for readability. Usually, in the derived classes, the keyword override is preferred for overridden virtual methods, because it will check at compile time that you actually override something. So you (usually) have:
class Base{
virtual void method();
};
class Derived : public Base {
void method() override; // still virtual
};
As for the = 0, you add it everywhere that there is no implementation, or where you want to force for a derived non abstract class (i.e. a class you want to instantiate in your code) to implement/override a certain method.
Note that override is only available if you use C++11 and above.
virtual void draw() = 0;
virtual void draw();
are both valid ways declaring the function in Shape.
The choice of whether to use the first one or the second one can be made based on what you expect Shape to do and what you expect its sub-types to do (Circle is the only one you have shown but there will be more I reckon).
If you expect that Shape can take care of some aspects of draw() but the derived classes must have their own implementation, then use the first option. Implement Shape::draw(). Derived classes can make use of Shape::draw() in their implementation.
If you expect that Shape can take care of all aspects of draw() for some classes, then use the second option. In this case, only those derived classes that need to override the function will override it and those that don't need to can leave it out of their implementation.
My suggestion will be to go with the first option. If there are some derived classes that don't need to do anything, they can call Shape::draw() and do nothing more. E.g.
class StrangeShape : public Shape
{
public:
void draw() override { Shape::draw(); }
};

Pure virtual functions and multiple inheritance

I have a (guaranteed tree-shaped) cascade of classes like
class rock_bottom {
...
virtual foo() = 0;
};
class A : rock_bottom {...}
class intermediate: rock_bottom {...}
class B : intermediate {...}
class higher_up {...}
class C : higher_up {...}
I want to implement foo() in the lettered classes A, B, C. Where do I need to declare foo? (Virtual? Pure?) Do I need (trivial) implementations in the middle layers intermediate and higher_up?
Question:
I want to implement foo() in the lettered classes A, B, C. Where do I need to declare foo? (Virtual? Pure?)
Answer:
That question needs to be asked in reverse. In which base class does it make sense to create the interface foo. Let's take some classes that you might find in application.
struct Shape {};
struct Rectangle : public Shape {};
struct Square : public Rectangle {};
struct Ellipse : public Shape {};
struct Circle : public Ellipse {};
It makes sense that all Shape be able to return their area and perimeter. So you put them as virtual member functions in Shape.
struct Shape
{
virtual double area() const = 0;
virtual double perimeter() const = 0;
};
Before you can create an instance of sub-type of Shape, you must implement them.
If you want to be able to create a Rectangle, those functions must be implemented in Rectangle since there are no other intermediate classes.
If you want to be able to create a Square, those functions must be implemented either in Rectangle, Square, or both.
Similarly, if you want to be able to create a Ellipse, those functions must be implemented in Ellipse since there are no other intermediate classes.
If you want to be able to create a Circle, those functions must be implemented either in Ellipse, Circle, or both.
However, only Rectangles have length and width. Only Ellipses have major radius and minor radius. It doesn't make sense to add virtual member functions in Shape to return those values.
Question:
Do I need (trivial) implementations in the middle layers intermediate and higher_up?
Answer:
No, you don't. The answer to the previous question should clarify that more.
Each override needs to be declared in the class that implements it; in your case, A, B and C, since you say each will provide an override.
There's no need to declare it in any intermediate class, assuming you're happy for them to remain abstract. They inherit the pure function from rock_bottom, and there's no point overriding that with another pure function.

Getting around base class constructor initialization, a bad habit?

I have a base class in an OpenGL project which represents 3DModel in general. Now I want to create a more specialized class that will inherits from 3DModel. My problem is the mandatory base class constructor call in the initialization list. Is there a proper way to delay this call until I've done some computation in the derived constructor?
Here's the important parts of the code:
class 3DModel {
public:
3DModel(std::vector<...> vertices){ ... };
[...]
private:
std::vector<...> vertices;
[...]
};
class Cylinder : public 3DModel {
public:
Cylinder(float top_bottom_ratio, float base_diameter);
[...]
};
//.cpp
Cylinder(float top_bottom_ratio, float base_width)
:3DModel(...) //<---- Mandatory
{
//I would like to calculate the cylinder vertices here
//and then feed them to the 3DModel constructor
}
Right now, I'm thinking of creating a dummy 3DModel() constructor and then call methods inside the derived constructor to modify the attributes of the base class. But this sounds really weird and it'll create a danger zone in the constructor where the object will be invalid for a few moment.
Another solution would be to thrash this class and simply do the computation inside the main program and use 3DModel constructor. But this is a sad solution and ruins the black-box approach.
Do you have any insights?
You can put the calculation into a helper function. Ideally, make it static, so you can't accidentally access unititialized base class values.
class Cylinder : public 3DModel {
public:
Cylinder(float top_bottom_ratio, float base_diameter);
[...]
private:
static calculateVertices(std::vector<...> vertices);
};
//.cpp
Cylinder(float top_bottom_ration, float base_width)
:3DModel(calculateVertices(top_bottom_ratio, base_width))
{
}
std::vector<...> Cylinder::calculateVertices(float top_bottom_ratio, float base_width) {
// calculate and return vertices here
}
You could also opt for composition instead of inheritance, where Cylindar has a 3DModel instead of being a 3DModel. (It would probably need to be something else, e.g. a Renderable that has a render() method.)
This is an example of the classic question of base-subclass vs composite. While the answer does give an example in the form of "base class - subclass", you really have to ask if this can't just be a class 'Cylinder' that contains the '3DModel' class. Unless your Cylinder subclass (and any other subclass) really adds more functionality to the 3DModel class, you really should make Cylinder a composite of the 3DModel class.

C++ array of base class which has instances of derived classes stored in the elements of the array

I am creating an application that allows a user to define dimensions for different shapes and returns the area to the user using the dimensions they specified.
My base class is Shape. Derived classes are Triangle, Circle, Square and Rectangle.
I have created an array of Shape in the hope of creating and storing instances of any of the derived classes in the array during runtime.
Shape** shape = new Shape*[TOTAL_SHAPES];
shape[i] = new Circle(radius);
I have managed this, however I am unable to access the instantiated classes methods. Sorry if this is a stupid question I am fairly new to C++.
Let's assume your types had the following definition
class Shape {
public:
void Method1() { ... }
};
class Circle : public Shape {
void Method2() { ... }
}
With this definition you could access methods on Shape by doing the following
shape[i]->Method1();
In this context though it wouldn't be possible to access Method2 though because the compiler only knows about Shape, not Circle.
shape[i]->Method2(); // Error!
You have three options:
Make Shape an abstract base class and call virtual methods that are members of Shape
Use static_cast to cast from a Shape* to a Circle*, and call methods through that.
Use dynamic_cast to cast from a Shape* to a Circle*, and call methods through that.
The first option is likely best in many cases. Among other reasons, you almost surely need to have a virtual destructor (which can be a by-product of making Shape an ABC), and you may prefer to not have to know what type of object is being pointed to, rather you'd like to simply call methods on whatever it may be. If you can use this idiom, use it.
The second option is dangerous. You must absolutely know that the object being pointed to is a Circle (or whatever) in order to use static_cast, else you will get Undefined Behavior.
The third option is only possible if your class is polymorphic, which means Shape must have at least one virtual method. You surely should have a virtual destructor, and this would serve that purpose.
How about that:
shape[i]->aMethod();
For starters, I highly recommend using a smart pointer wrapper instead of using raw pointers (especially if you are new to the language).
std::vector<std::shared_ptr<Shape>> shapes(TOTAL_SHAPES);
That will define a vector with an initial size of TOTAL_SHAPES.
To the root of your problem, any method you wish to call using a Shape* must be valid for Shape, or you must do a risky downcast to the appropriate type. For example:
class Shape
{
public:
// constructors and other methods go here
virtual ~Shape() { } // virtual destructor
virtual void Draw() { } // virtual function to be used by derived classes
};
class Circle
{
public:
// ...
virtual ~Circle() { }
virtual void Draw() { } // override the virtual function
};
Then, in your application code,
std::vector<std::shared_ptr<Shape>> shapes(TOTAL_SHAPES);
shapes[0] = std::make_shared(new Circle);
shapes[0]->Draw(); // calls Circle::Draw
Note that depending on your usage, std::unique_ptr may replace std::shared_ptr.

concept of virtual functions in c++?

I read so many blogs and I understand how to use virtual function in c++. But, still I don't understand why we use virtual functions. Can you give me a real world example so that I can more easily visualize the actual meaning of virtual function.
An important thing to mention is that inheritance (which the keyword virtual is fundamental for) should not be for the sole purpose of code re-use, use delegation for this.
Delegation would be when we have a class say BroadbandConnection with a method called connection(). Then your manager says we want to add encryption, so you create a class BroadbandConnectionWithEncryption. Your natural instinct may be to use inheritance and then make the new class BroadbandConnectionWithEncryption derive from BroadbandConnection.
Drawback's to this is that the creator of the initial class had not designed it for inheritance so you would need to change its definition to make the method connection() virtual so you can override its behavior in the derived class. This is not always ideal. A better idea is to use delegation here for the purpose of code reuse.
class BroadBandConnection
{
public:
void Connection (string password)
{
//connection code.
}
};
class BroadBandConnectionWithEndcryption
{
public:
void Connection (string password)
{
mbroadbandconnection.Connection(password);
//now do some stuff to zero the memory or
//do some encryption stuff
}
private:
BroadBandConnection mbroadbandconnection;
};
The keyword virtual is used for the purpose of polymorphism. As the name suggest, it is the ability for an object to have more than one form. This sort of decision would be made at the time of designing an interface or class.
class IShape
{
virtual void Draw () = 0;
};
class Square
{
void Draw()
{
//draw square on screen
}
};
class Circle
{
void Draw()
{
//draw circle on screen
}
};
I made Draw() pure virtual with the = 0. I could have left this out and added some default implementation. Pure virtual makes sense for Interfaces where there is no reasonable default implementation.
What this lets me do is pass around a Shape object to various methods and they do not need to be concerned with what I have just given them. All they know is that I have to provide something that supports the ability for a shape to draw itself.
IShape* circle = new Circle ();
IShape* square = new Square ();
void SomeMethod (IShape* someShape)
{
someShape->Draw(); //This will call the correct functionality of draw
}
In the future as people begin thinking of new shapes, they can derive from IShape and so long as they implement some functionality for Draw. They can pass this object to SomeMethod.
First, this.
Now, a real life example. I have a program with a GUI with three tabs. Each tab is an object of a class that derives from a common base, TabBase. It has a virtual function OnActivate(). When a tab is activated, the dispatcher calls it on the current tab. There's some common action and there are actions that are specific to this tab. This is implemented via virtual functions.
The benefit is that the controller does not need to know what kind of tab it is. It stores an array of TabBase pointers, and just calls OnActivate() on them. The magic of virtual functions makes sure the right override is called.
class TabBase
{
virtual void OnActivate()
{
//Do something...
}
};
class SearchTab: public TabBase
{
void OnActivate() //An override
{
TabBase::OnActivate(); //Still need the basic setup
//And then set up the things that are specific to the search tab
}
}
We have one base class (animal) that have method, that can be implemented differently by it's children (say). When we declare this method virtual, we can adress that method and it will be implemented from it's children's definition. You don't have to use virtual if you adress children's overloaded methods, but you have to, when you adress parent's methods.
For example, if you have a vector of animals each one of whom is different. You declare method (say) as virtual and call it from animal class and it will be called from corresponding child.
Correct me if I'm wrong, that's how I understood it.
They actually give an example on Wiki
http://en.wikipedia.org/wiki/Virtual_function
using animals. Animals is the super class, all animals eat (the superclass virtual function). Each animal may eat differently than all the other animals (overriding the virtual function). I have a list of arbitrary animals, and when I call the eat function, they will display their own differing eating habit.
If you are familiar with Java - that should be easy. In Java, ALL class methods are effectively virtual. If you override it in a derived class, and you call it via a base class reference, the override will be called, not the base.
That's not the default behavior in C++. If you want a function to behave in that way, you have to declare it as virtual in the base class. Easy enough.
Java is choke full of virtual functions. It just does not have an explicit keyword for them.
The purpose of virtual functions is to achieve dynamic dispatch.
You say you are familiar with Java, so then for a real world use of virtual functions, think of any place in Java where you would have used an interface or used #Override on a public/protected method.
The decision to use virtual functions is a simple matter. You just need to know when you'd want to override a base method. Take the following code as an example:
class animal
{
public:
void sound()
{
cout << "nothing";
}
};
class bird : public animal
{
public:
void sound()
{
cout << "tweet";
}
};
In this case, I'd want to override bird(). But what if I didn't? This is what would happen:
animal * a = new bird;
a->sound();
**Output**
nothing
The screen would say nothing because for all intents and purposes, C++ only sees an animal. However, if you declared it virtual, it knows to search for the lowest method in the class hierachy. Try it again:
class animal{
public:
virtual void sound(){cout<<"nothing";}
};
class bird : public animal
{
public:
void sound()
{
cout << "tweet";
}
};
animal * a = new bird;
a->sound();
**Output**
tweet.
Hope this helps.