Public member without inheritance - c++

I have a base class which looks something like this:
class Base
{
public:
typedef std::shared_ptr<Base> ptr_t;
typedef std::weak_ptr<Base> wptr_t;
enum class Type { foo, bar, baz };
Type x;
// ...
};
I'd like those internal types to be public so that I can do stuff like Base::ptr_t my_ptr(new Base); and so on. But if I make a new class like this...
class Derived : public Base
{
// ...
};
unfortunately, Derived::ptr_t is still a Base pointer. I'd like Derived to publicly inherit x from Base, but not inherit ptr_t,wptr_t, or Type. For example
Derived a;
a.x = Base::Type::foo; // this should work
a.x = Derived::Type::foo; // but I want this to fail
Is this possible, perhaps though some magic use of friend or virtual or something like that?

Simply override the type:
class Derived {
typedef int Type;
};
It will not allow the use of Derived::Type (as it's private as well as typedefed)

class Derived : public Base
{
// This is now private
using Base::ptr_t;
using Base::wptr_t;
// ...
};

Based on the answers of iammilind and Luc Danton, here's what I've come up with:
class Base
{
private:
// only 'BaseClass' is allowed to derive from Base
Base() { }
friend class BaseClass;
public:
typedef std::shared_ptr<Base> ptr_t;
typedef std::weak_ptr<Base> wptr_t;
enum class Type { foo, bar, baz };
Type x;
// ...
};
class BaseClass : public Base
{
private:
// make all the raw_Base types private
using Base::ptr_t;
using Base::wptr_t;
using Base::Type;
};
class Derived : public BaseClass
{
// define as usual, and now all is well in the world.
};
// now, to test it
class Derived2 : public Base { }; // fails
Derived d;
d.x = Derived::Type::foo; // fails
d.x = Base::Type::foo; // works
// Which is exactly what I wanted.
As far as I can tell, the only problem with this solution is that it adds a new and potentially confusing class. The class is defined in such a way that it can't really be misused – Base itself cannot be derived from except by BaseClass, but still, BaseClass is an unattractive piece of namespace-clutter.
However, for the particular piece of code that I intend to use this in, I happen to be using the equivalent of BaseClass already to solve an unrelated problem. So this BaseClass technique suits my purposes just fine.

Related

How do I inherit only the member functions in C++?

Say I have a base class Base, and a derived class Derived.
class Base
{
public:
void f1(void);
...
int data1;
...
};
class Derived : Base
{
... add stuff here that's unique to Derived
};
How can Derived inherit only the functions (i.e., f1()) and NOT the data (i.e., data1) from Base?
having attribute of a base class that is not needed in derived class is a hint for bad inheritance
in your case i assume you are going to have another derived class that needs those data members, otherwise it wouldnt make sense
then why not do something like this:
class Base
{
public:
void f1(void);
...
};
class DerivedClass : Base
{
... add stuff here that's unique to Derived
};
class DerivedClass2 : Base
{
public:
int data1;
....
}
if you have more derived classes that needs those data member i suggest you to make separate base class, one for functions and one for data members.

Superclass Setting Object of Subclass Data

I have a base class in C++ that has some protected member variables (although, I do not think it is relevant that it is protected vs. private in this case).
I have a derived class that derives from this base class. In it, there is a public function that creates an object of the base class and returns that object. However, in that function I need to be able to set the protected member variables into a special state.
Example:
class Base
{
protected:
int b_value;
};
class Derived : public Base
{
public:
Base createBase()
{
Base b;
b.b_value = 10;
return b;
}
};
I specifically only want the derived class to be able to the protected member variable. I do not want a public accessor method in the base class.
I originally tried to fix this by making the derived class's createBase() function be a friend of the Base class. Like so:
class Base
{
protected:
int b_value;
friend Base Derived::createBase();
};
class Derived : public Base
{
public:
Base createBase()
{
Base b;
b.b_value = 10;
return b;
}
};
As you can see, this will not compile since Derived has not been defined yet. If it matters, these two classes are defined in separate header files. I guess one way to describe this problem is a "chicken and egg" problem where one needs the other first.
I have a feeling this has to be a "I am not designing my classes correctly and need to rethink how I am doing this" but I cannot figure out how to get this to work.
You can forward declare Derived and then make it a friend in Base :
class Derived;
class Base
{
friend class Derived;
protected:
int b_value;
};
class Derived : public Base
{
public:
Base createBase()
{
Base b;
b.b_value = 10;
return b;
}
};
However this design seems seriously flawed to me as you already stated, you should probably make createBase() a static public method in your Base class and have a setter for b_value or a constructor that sets it.
Remember that right now inside createBase(), this->b_value is also available.

Is there an interface mechanism for nested enum classes?

In C++, pure virtual functions provide the functionality of an interface. That is, any subclasses must implement all pure-virtual functions in the base class:
class myClass {
virtual bool implementme() = 0; // MUST be implemented
};
class mySubClass : public myClass {
bool implementme() {} // REQUIRED
};
Is there a similar mechanism for nested (enum) classes? That is, I'm looking for something like
class myClass {
virtual enum class myEnum = 0; // MUST be implemented
};
class mySubClass : public myClass {
enum class myEnum {}; // REQUIRED
};
Since you say that the implementer is not part of your code base (thus not producing a compile error), I must assume you are writing a library, and that the code which uses this enum is in the consumer of the library.
I would recommend that you use CRTP as follows:
class myClass {
};
template<typename T> class myClassImpl : public myClass {
static_assert(std::is_enum<typename T::myEnum>::value, "Subclasses of myClassImpl must provide the myEnum enum class");
};
class mySubClass : public myClassImpl<mySubClass> {
enum class myEnum {};
};
This wouldn't make a whole lot of sense. Someone could only have visibility to only the base class (not the derived class) and get back a myEnum from the return of some virtual function, where myEnum is an incomplete type. There is no mechanism for virtual types of any kind, including enums. Do you really want a virtual table looking up your type anyway?

C++ reference sub class in super class

I am little bit confused on referencing a sub class inside a super class in C++.
For example, given Java :
public class Entity {
protected ComplexEntity _ce;
public Entity() {
}
public ComplexEntity getCentity() {
return _ce;
}
}
Where ComplexEntity extends the entity.It works.In the sub class I call getCentity() no errors.
Now ,in C++ when I write something like that:
#pragma once
#include "maininclude.h"
#include "ExtendedEntity.h"
using namespace std;
class EntityBase
{
public:
EntityBase(void);
EntityBase(const string &name);
~EntityBase(void);
protected:
ExtendedEntity* _extc;
string _name;
};
I am getting compiler error:
error C2504: 'Entity' : base class undefined
In the classes which inherit from this Entity.Why does that happen?
Is it completely unacceptable in C++?
May be Entity must be abstract ?
I would like to get suggestions on possible workarounds.
You may consider using CRTP, cut/paste from Wikipedia:
// The Curiously Recurring Template Pattern (CRTP)
template<class Derived>
class Base
{
Derived* getDerived() { return static_cast<Derived*>(this); }
};
class Derived : public Base<Derived>
{
// ...
};
Your code is like the following:
struct D : B {}; // error: B doesn't mean anything at this point
struct B {
D *d;
};
Your header ExtendedEntity.h is trying to use the definition of Entity before Entity is defined.
You need to change your code to this:
struct D;
struct B {
D *d;
};
struct D : B {};
A class in C++ needs to know the size of all its members and of all its superclasses. Class Entity does not know the size of it's subclass ComplexEntity, unless class ComplexEntity is defined before class Entity. But then, class ComplexEntity does not know the size of its superclass Entity.
This problem exists in C++, because class members are accessed using simple offset calculation. You can work around this, by forward declaring the derived class and using pointers as members:
class Extended; // declare the derived class
class Base { // define the base class
Extended* e; // you cannot use Extended e here,
// because the class is not defined yet.
};
class Extended : public Base {}; // define the derived class

c++ How do you call a templated base-class function from derived class instance

Found related questions but not the exact variant so I am posting a very simple question.
A derived class inherits from a templated base, and I want to call the base function, how to do it?
template <class A>
class testBase {
public:
void insert(const A& insertType) {
// whatever
}
};
class testDerived : testBase<double> {
// whatever
};
int main() {
testDerived B;
// Compiler doesn't recognize base class insert
// How do you do this?
B.insert(1.0);
}
Need public inheritance (default is private for class):
class testDerived : public testBase<double> {
A class has a default access level of 'private'. You basically inherited 'testBase' using private inheritance so that testBase's public interface is not part of testDerived's. Simple solution:
class testDerived: public testBase<double> {...};
I do wish C++ applied public inheritance by default though since that's generally a much more common case. Then again, we could just all use structs instead. :-D