Due to a mistake when designing an interface, a third-party software provider deleted a function, like the copy constructor in class base_noncopy_base:
class base_noncopy_base {
base_noncopy_base(const base_noncopy_base&);
public:
base_noncopy_base() {}
};
That class is supposed to be inherited, like:
class base_noncopy_derived : public base_noncopy_base {
// whatever ....
};
But now, it is no longer allowed to use base_noncopy_derived as a base_noncopy_base:
int main() {
base_noncopy_derived d;
// base_noncopy_base b1 = d; // won't compile
// base_noncopy_base b2(d); // won't compile
// base_noncopy_base b3((base_noncopy_derived)d); // won't compile
}
It is possible to const_cast a const member, and I have seen some hacks out there to access private members from outside a class, of course, only to be used in emergency cases. I am wondering: would there be any possibility of hacking the deletion of a function out?
Edit 1:
Elaborating further the question:
The actual problem arises from other third-party functions functions, like:
void base_noncopy_function1(base_noncopy_base &b) {
}
void base_noncopy_function2(base_noncopy_base b) {
}
I can use something like:
base_noncopy_base *b4 = &d;
base_noncopy_function1(*b4);
But not
base_noncopy_function2(*b4);
If you want to "use base_noncopy_derived as a base_noncopy_base", then use a reference or pointer rather than creating a new object:
base_noncopy_derived d;
base_noncopy_base & b = d;
Your commented-out code attempts to slice the base class, creating a new object by copying just part of d. This is rarely a sensible thing to do, and the reason why base classes tend to be abstract or non-copyable.
If you really want to do this, then you'll have to change the definition of the base class so that it doesn't delete the copy functions. There's no way to "undelete" them.
Related
Basically, I have one class that owns another object:
class A()
{
A() { initSystems() };
void initSystems();
B b;
}
class B()
{
B() { //Does stuff that requires 'initSystems()' to be called before }
}
and for 'B' to function, the init systems function needs to be called in A. Is there any 'nice' way to work around this? Like creating the 'B' object later or something?
Sounds like your classes are too tightly coupled. There's many ways to fix this, but it depends on the rest of your design.
Maybe A shouldn't own a B, since A is a dependency of B. You could inject an instance of A into each B as they get instantiated.
Maybe B shouldn't exist and all, and it should be merged into A:
class A()
{
A() {
initSystems();
//Does stuff that requires 'initSystems()' to be called before
}
void initSystems();
// B's methods
}
It's my opinion that most initialization methods are code smells (that is, it suggests a bad design). Some people have given this pattern a name: "Design Smell: Temporal Coupling"
If you desire to keep the B a regular member of A, the two places you can run code before the construction of b are:
the constructor of a base class of A,
in the initializer list of a member of A, for a member declared above b.
If you wish to defer construction of the B, you need to hold the object by indirection or later construct it onto raw storage and when destroying, perform placement destruction.
Most of this has strange smells to it, it may be beneficial to reorganize your code to avoid this kind of structure.
You simply need to change your design so initSystems() is requirement for both A and B.
If you can't do this (although you really should), there are other ways, like dynamic allocation:
class A()
{
A() {
initSystems();
b = std::make_unique<B>();
};
void initSystems();
std::unique_ptr<B> b;
}
I agree with #nanny over the decoupling of the class and merging if possible.
But your scenario seems like in which B is separate entity in your system, hence a class. And A contains a B, hence the composition.
So one way of solving this would be, you keep a reference (pointer) to B in A instead of making B a part of A.
Or you should not access the stuff that is created in initInstance() of A in the constructor of B, and create a method postConstruct in B that you can call from A after call initInstance. Following code explains it,
class A()
{
A()
{
initSystems();
b.postContruct()
}
void initSystems()
{
// do the init instance stuff here.
}
B b;
}
class B()
{
B() {}
void postContruct()
{
//Does stuff that requires 'initSystems()' to be called before
}
}
If you have a feature rich class, possibly one you do not own/control, it is often the case where you want to add some functionality so deriving makes sense.
Occasionally you want to subtract as well, that is disallow some part of the base interface. The common idiom I have seen is to derive and make some member functions private and then not implement them. As follows:
class Base
{
public:
virtual void foo() {}
void goo() { this->foo(); }
};
class Derived : public Base
{
private:
void foo();
};
someplace else:
Base * b= new Derived;
and yet another place:
b->foo(); // Any way to prevent this at compile time?
b->goo(); // or this?
It seems that if the compilation doesn't know that it is derived, the best you can do is not implement and have it fail at runtime.
The issue arises when you have a library, that you can't change, that takes a pointer to base, and you can implement some of the methods, but not all. So part of the library is useful, but you run the risk of core dumping if you don't know at compile time which functions will call what.
To make it more difficult, others may inherit from you class and want to use the library, and they may add some of the functions you didn't.
Is there another way? in C++11? in C++14?
Let's analyze this, focused on two major points:
class Base
{
public:
virtual void foo() {} // This 1)
// ...
class Derived : public Base // and this 2)
In 1) you tell the world that every object of Base offers the method foo() publicly. This implies that when I have Base*b I can call b->foo() - and b->goo().
In 2) you tell the world that your class Derived publicly behaves like a Base. Thus the following is possible:
void call(Base *b) { b->foo(); }
int main() {
Derived *b = new Derived();
call(b);
delete b;
}
Hopefully you see that there is no way call(Base*) can know if b is a derived and thus it can't possibly decide at compile-time if calling foo wouldn't be legal.
There are two ways to handle this:
You could change the visibility of foo(). This is probably not what you want because other classes can derive from Base and someone wants to call foo afterall. Keep in mind that virtual methods can be private, so you should probably declare Base as
class Base
{
virtual void foo() {}
public:
void goo() { this->foo(); }
};
You can change Derived so that it inherits either protected or private from Base. This implies that nobody/only inheriting classes can "see" that Derived is a Base and a call to foo()/goo() is not allowed:
class Derived : private Base
{
private:
void foo() override;
// Friends of this class can see the Base aspect
// .... OR
// public: // this way
// void foo(); // would allow access to foo()
};
// Derived d; d.goo() // <-- illegal
// d.foo() // <-- illegal because `private Base` is invisible
You should generally go with the latter because it doesn't involve changing the interface of the Base class - the "real" utility.
TL;DR: Deriving a class is a contract to provide at least that interface. Subtraction is not possible.
This seems to be what you want to do:
struct Library {
int balance();
virtual int giveth(); // overrideable
int taketh(); // part of the library
};
/* compiled into the library's object code: */
int Library::balance() { return giveth() - taketh(); }
/* Back in header files */
// PSEUDO CODE
struct IHaveABadFeelingAboutThis : public Library {
int giveth() override; // my implementation of this
int taketh() = delete; // NO TAKE!
};
So that you can't call taketh() on an IHaveABadFeelingAboutThis even when it is cast as the base class.
int main() {
IHaveABadFeelingAboutThis x;
Library* lib = &x;
lib->taketh(); // Compile error: NO TAKE CANDLE!
// but how should this be handled?
lib->balance();
}
If you want to present a different interface than the underlying library you need a facade to present your interface instead of the that of the library.
class Facade {
struct LibraryImpl : public Library {
int giveth() override;
};
LibraryImpl m_impl;
public:
int balance() { return m_impl.balance(); }
virtual int giveth() { return m_impl.giveth(); }
// don't declare taketh
};
int main() {
Facade f;
int g = f.giveth();
int t = f.taketh(); // compile error: undefined
}
Although I don't think your overall situation is good design, and I share many of the sentiments in the comments, I can also appreciate that a lot of code you don't control is involved. I don't believe there is any compile time solution to your problem that has well defined behavior, but what is far preferable to making methods private and not implementing them is to implement the entire interface and simply make any methods you can't cope with throw an exception. This way at least the behavior is defined, and you can even do try/catch if you think you can recover from a library function needing interface you can't provide. Making the best of a bad situation, I think.
If you have class A:public B, then you should follow the https://en.wikipedia.org/wiki/Liskov_substitution_principle
The Liskov substitution principle is that a pointer-to-A can be used as a pointer-to-B in all circumstances. Any requirements that B has, A should satisfy.
This is tricky to pull off, and is one of the reasons why many consider OO-style inheritance far less useful than it looks.
Your base exposes a virtual void foo(). The usual contract means that such a foo can be called, and if its preconditions are met, it will return.
If you derive from base, you cannot strengthen the preconditions, nor relax the postconditions.
On the other hand, if base::foo() was documented (and consumers of base supported) the possibility of it throwing an error (say, method_does_not_exist), then you could derive, and have your implementation throw that error. Note that even if the contract says it could do this, in practice if this isn't tested consumers may not work.
Violating the Liskov substitution principle is a great way to have lots of bugs and unmaintainable code. Only do it if you really, really need to.
i am pretty sure this is a simple question for a long time c++ user, this should be a pattern or the problem should be solved in any other way but given i am Python developer and a total novice with c++ i don't know how it's usually done.
Suppose that i have a class where i want to store a pointer to an object that can be of 1 of two different classes that respects an interface, for example:
class AllPlayers
{
public:
virtual void play();
};
class VlcPlayer: public AllPlayers
{
public:
virtual void play();
};
class Mplayer: public AllPlayers
{
public:
virtual void play();
};
class MyMediaPlayer
{
public:
MyMediaPLayer(int playerType);
AllPlayers m_player;
};
MyMediaPlayer::MyMediaPlayer(int PlayerType)
{
if (PlayerType == 0) {
VlcPlayer tmp_player;
m_player = static_cast<AllPlayers> (tmp_player);
}
else {
Mplayer tmp_player;
m_player = static_cast<AllPlayers> (tmp_player);
}
}
MyMediaPlayer test(0);
test.play();
First, i know this would not work and that it seems pretty normal why but how could i get this effect? i would like to have a member of a class for what i am going to use ever the same methods, implemented using a interface and i would like to avoid trying to cast to every of the derived classes every time i am going to use one of his methods.
C++ is value-based, i.e., if you create an object of a given type you really have an object of this type. This doesn't play nicely with dynamic polymorphism. To get dynamic polymorphism you use a pointer or a reference to the actual object. To also get the life-time straight you typicslly allocate the corresponding object on the stack (make sure your base class has a virtual destructor if you ever release an object of a derived type using a pointer to the base). With this, you should be all set: just call a virtual function of the base class through a pointer to rhe base: When you overridethe function in the derived class this is the function which is called.
If you write
AllPlayers m_player;
that is going to be an instance of AllPlayers and cannot be an instance of a class that derives from it.
You should instead use a pointer and allocate the class on the stack.
For example:
class MyMediaPlayer
{
public:
MyMediaPLayer(int playerType);
~MyMediaPLayer();
AllPlayers m_player;
};
MyMediaPlayer::MyMediaPlayer(int PlayerType)
{
if (PlayerType == 0) {
m_player = new VlcPlayer;
}
else {
m_player = new Mplayer;
}
}
MyMediaPlayer::~MyMediaPlayer()
{
if (0 != m_player) {
delete m_player;
m_player = 0;
}
}
As suggested by #xception use of unique_ptr may relieve you from having to write code to deallocate the instance.
As correctly pointed out by #DietmarKühl you should always declare a virtual destructor in a root class (a base class that does not itself derives from some other class) as is the case with AllPlayers.
class AllPlayers
{
public:
virtual ~AllPlayers();
virtual void play(); // note: this should probably be pure virtual.
};
The reason this will not work is colloquially known as Object Splicing. (Or, for those Harry Potter readers out there, Object Splinching)
Let's look at an example:
class Foo
{
public:
int bob;
float fred;
// Foo(const Foo& otherfoo); // implicit copy constructor
};
class Bar : public Foo
{
public:
double gabe; // gabe newell is fat
char steve; // steve jobs is thin
// Bar(const Bar& otherbar); // implicit copy constructor
};
int main()
{
Foo f;
Bar b;
f.bob = 10;
f.fred = 1.5;
b.bob = 15;
b.fred = 2.5;
b.gabe = 1.77245385091; // sqrt(pi)
b.steve = -4;
f = Foo(b);
return 0;
}
This is legal and valid. Problem is, the implicit copy constructor of Foo is called, and Foo's copy constructor knows nothing about what a Bar is. Only that it contains everything a Foo has, and some extra irrelevant crap. Because of this, only the Foo's data gets preserved; the data unique to the Bar gets spliced off.
It's important to note that this is DEFINED BEHAVIOR: it's doing EXACTLY WHAT YOU TELL IT TO. Casting between a subclass of a base class and a base class is implicit. Furthermore, the behavior of the copy constructor is implicit.
It's also important to note that, under the hood, C++ pointers and references work in the same way. It's perfectly sane to pass the Bar to Foo's copy constructor by reference, this pass by reference does not produce a copy of the object. It's the same as working with a pointer.
The actual splicing takes place as a direct result of the copy constructor biting off more than it can chew. It gets an object with more state than it expected, and its only choice is to ignore the extra state.
With python, this doesn't happen because everything is implicitly stored as a reference type. Since you only work with references (the objects themselves are abstracted away), you never have the opportunity to accidentally splice an object.
class a
{
private:
b *b_obj;
public:
void set(int);
};
a::a()
{
b_obj = new b;
}
a::set(int s)
{
b_obj->c = s;
}
class b
{
public:
int c;
};
is this code valid?
if no, how do i make b_obj of a particular object (say a_obj) of class a ,modifiable in another class c...if a_obj i created in another class d....i am scared of a_obj going out of scope in class c.
hope you understand my question.
thanks a lot for taking the time to read my post
The code is nearly valid. class b needs to be declared (or at least forward declared) before it is referred to in class a, you do not specify the return type in the definition for a::set, and you have not provided a declaration for a'a default constructor. Here is the revised code, along with a test harness:
class b
{
public:
int c;
};
class a
{
private:
b *b_obj;
public:
a();
void set(int);
};
a::a()
{
b_obj = new b;
}
void a::set(int s)
{
b_obj->c = s;
}
int main()
{
a my_a;
my_a.set(42);
}
Now, just because the code is valid doesn't mean it's good:
You don't initialize c when default-constructing b.
You use raw pointers to dyanamically-allocated b's. Use automatic variables instead, whenever possible. Among the the reasons for this are ...
You never delete the b you new'ed in a'a constructor. This results in a memory leak. If you had avoided the use of dynamic allocation in the first place, this would not be an issue.
Well,
*b_obj = *other_b_obj;// equality of objects values
b_obj = other_b_obj; // equality for pointer values
assuming that b_obj is an object and other_b_obj is a pointer:
b_obj = *other_b_obj;
Assuming the reverse:
b_obj = &other_b_obj;
Assuming both are pointers:
b_obj = other_b_obj;
for your final question, new is not compulsory for assgining pointers. A pointer may point to an exiting object. However, if you want the pointer to point to a new object, use then new keyword, which attempts to create new object and returns the new object address.
is this code valid?
The code is almost valid, except that you forgot to state the return type of the set function:
void a::set(int s)
However, the set function will really change the c member of b_obj. It is public, so the compiler will allow it.
BTW, why don't you try for yourself?
As an aside, while you're studying, look at constructors, destructors, assignment operator and implement them to free the object b_obj properly. You can even use a shared_ptr for that.
Also, I wouldn't advise you to use such a dull name as lowercase a for a class.
I'm having trouble understanding what the purpose of the virtual keyword in C++. I know C and Java very well but I'm new to C++
From wikipedia
In object-oriented programming, a
virtual function or virtual method is
a function or method whose behavior
can be overridden within an inheriting
class by a function with the same
signature.
However I can override a method as seen below without using the virtual keyword
#include <iostream>
using namespace std;
class A {
public:
int a();
};
int A::a() {
return 1;
}
class B : A {
public:
int a();
};
int B::a() {
return 2;
}
int main() {
B b;
cout << b.a() << endl;
return 0;
}
//output: 2
As you can see below, the function A::a is successfully overridden with B::a without requiring virtual
Compounding my confusion is this statement about virtual destructors, also from wikipedia
as illustrated in the following example,
it is important for a C++ base class
to have a virtual destructor to ensure
that the destructor from the most
derived class will always be called.
So virtual also tells the compiler to call up the parent's destructors? This seems to be very different from my original understanding of virtual as "make the function overridable"
Make the following changes and you will see why:
#include <iostream>
using namespace std;
class A {
public:
int a();
};
int A::a() {
return 1;
}
class B : public A { // Notice public added here
public:
int a();
};
int B::a() {
return 2;
}
int main() {
A* b = new B(); // Notice we are using a base class pointer here
cout << b->a() << endl; // This will print 1 instead of 2
delete b; // Added delete to free b
return 0;
}
Now, to make it work like you intended:
#include <iostream>
using namespace std;
class A {
public:
virtual int a(); // Notice virtual added here
};
int A::a() {
return 1;
}
class B : public A { // Notice public added here
public:
virtual int a(); // Notice virtual added here, but not necessary in C++
};
int B::a() {
return 2;
}
int main() {
A* b = new B(); // Notice we are using a base class pointer here
cout << b->a() << endl; // This will print 2 as intended
delete b; // Added delete to free b
return 0;
}
The note that you've included about virtual destructors is exactly right. In your sample there is nothing that needs to be cleaned-up, but say that both A and B had destructors. If they aren't marked virtual, which one is going to get called with the base class pointer? Hint: It will work exactly the same as the a() method did when it was not marked virtual.
You could think of it as follows.
All functions in Java are virtual. If you have a class with a function, and you override that function in a derived class, it will be called, no matter the declared type of the variable you use to call it.
In C++, on the other hand, it won't necessarily be called.
If you have a base class Base and a derived class Derived, and they both have a non-virtual function in them named 'foo', then
Base * base;
Derived *derived;
base->foo(); // calls Base::foo
derived->foo(); // calls Derived::foo
If foo is virtual, then both call Derived::foo.
virtual means that the actual method is determined runtime based on what class was instantiated not what type you used to declare your variable.
In your case this is a static override it will go for the method defined for class B no matter what was the actual type of the object created
So virtual also tells the compiler to call up the parent's destructors? This seems to be very different from my original understanding of virtual as "make the function overridable"
Your original and your new understanding are both wrong.
Methods (you call them functions) are always overridable. No matter if virtual, pure, nonvirtual or something.
Parent destructors are always called. As are the constructors.
"Virtual" does only make a difference if you call a method trough a pointer of type pointer-to-baseclass. Since in your example you don't use pointers at all, virtual doesn't make a difference at all.
If you use a variable a of type pointer-to-A, that is A* a;, you can not only assign other variables of type pointer-to-A to it, but also variables of type pointer-to-B, because B is derived from A.
A* a;
B* b;
b = new B(); // create a object of type B.
a = b; // this is valid code. a has still the type pointer-to-A,
// but the value it holds is b, a pointer to a B object.
a.a(); // now here is the difference. If a() is non-virtual, A::a()
// will be called, because a is of type pointer-to-A.
// Whether the object it points to is of type A, B or
// something entirely different doesn't matter, what gets called
// is determined during compile time from the type of a.
a.a(); // now if a() is virtual, B::a() will be called, the compiler
// looks during runtime at the value of a, sees that it points
// to a B object and uses B::a(). What gets called is determined
// from the type of the __value__ of a.
As you can see below, the function A::a is successfully overridden with B::a without requiring virtual
It may, or it may not work. In your example it works, but it's because you create and use an B object directly, and not through pointer to A. See C++ FAQ Lite, 20.3.
So virtual also tells the compiler to call up the parent's destructors?
A virtual destructor is needed if you delete a pointer of base class pointing to an object of derived class, and expect both base and derived destructors to run. See C++ FAQ Lite, 20.7.
You need the virtual if you use a base class pointer as consultutah (and others while I'm typing ;) ) says it.
The lack of virtuals allows to save a check to know wich method it need to call (the one of the base class or of some derived). However, at this point don't worry about performances, just on correct behaviour.
The virtual destructor is particulary important because derived classes might declare other variables on the heap (i.e. using the keyword 'new') and you need to be able to delete it.
However, you might notice, that in C++, you tend to use less deriving than in java for example (you often use templates for a similar use), and maybe you don't even need to bother about that. Also, if you never declare your objects on the heap ("A a;" instead of "A * a = new A();") then you don't need to worry about it either. Of course, this will heavily depend on what/how you develop and if you plan that someone else will derive your class or not.
Try ((A*)&b).a() and see what gets called then.
The virtual keyword lets you treat an object in an abstract way (I.E. through a base class pointer) and yet still call descendant code...
Put another way, the virtual keyword "lets old code call new code". You may have written code to operate on A's, but through virtual functions, that code can call B's newer a().
Say you instantiated B but held it as an instance of an A:
A *a = new B();
and called function a() whose implementation of a() will be called?
If a() isn't virtual A's will be called. If a() was virtual the instantiated sub class version of a() would be called regardless of how you're holding it.
If B's constructor allocated tons of memory for arrays or opened files, calling
delete a;
would ensure B's destructor was called regardless as to how it was being held, be it by a base class or interface or whatever.
Good question by the way.
I always think about it like chess pieces (my first experiment with OO).
A chessboard holds pointers to all the pieces. Empty squares are NULL pointers. But all it knows is that each pointer points a a chess piece. The board does not need to know more information. But when a piece is moved the board does not know it is a valid move as each pice has different characteristica about how it moves. So the board needs to check with the piece if the move is valid.
Piece* board[8][8];
CheckMove(Point const& from,Point const& too)
{
Piece* piece = board[from.x][from.y];
if (piece != NULL)
{
if (!piece->checkValidMove(from,too))
{ throw std::exception("Bad Move");
}
// Other checks.
}
}
class Piece
{
virtual bool checkValidMove(Point const& from,Point const& too) = 0;
};
class Queen: public Piece
{
virtual bool checkValidMove(Point const& from,Point const& too)
{
if (CheckHorizontalMove(from,too) || CheckVerticalMoce(from,too) || CheckDiagonalMove(from,too))
{
.....
}
}
}