2

Big edit:

I have a code in which I have to add a constant member in a inherited class by using _elemente (which is a vector). Not to add a member in the inherited classes, just by using _elemente. In every inherited classes (let's say B, C, D and E) I withh have MAX_VAL1, MAX_VAL2 and so on with different values. I tried:

#include <iostream>
#include <iomanip>
#include <vector>
typedef unsigned int Uint;
typedef vector<Uint> TVint;
typedef vector<Uint>::const_iterator TIterator;

class A
{
protected:
Uint _count;
TVint _elemente;
public:
//
};

class B : public A
{
    const int MAX_VAL;
};

But it has a member and I don't have to have a member in the inherited class.

All the code here:

.h: http://pastebin.com/P3TZhWaV
.cpp: http://pastebin.com/ydwy2L5a

The work from the inherited classes is done using that constant members.

if MAX_VAL1 < count
{
throw Exception() {}
}
 if (_elemente.size() == 0) // As _elemente is a vector from STL
{
    _elemente.push_back(0);
}
for (int i = _elemente.size(); i < count; i++)
{
    _elemente.push_back(_elemente[i * (i+1) / 2]);
}
}

I don't think that is correct as I have to use the Vector from STL and I don't really think that is the way the constant member from a inherited class without the actual member declared should be added. Thanks for your help.

Box Box Box Box
  • 5,094
  • 10
  • 49
  • 67
  • 2
    What do you want to achieve with this code? It isn't clear –  Apr 22 '16 at 14:27
  • 2
    If you are using a `std::vector<>` you shouldn't need a `MAX_VAL` for bounds checking. Just use the `.at()` instead of `[]` notation and you'll get an error thrown for you. If you need a const value in your base class, you can have a const value in your base class which must be initialized via initializer list in the CTOR, derived classes can call the base class CTOR via initializer list as well to set the value upon construction. – RyanP Apr 22 '16 at 14:30
  • @RyanP I'd suggest posting the bit about the base constructor as an answer. That might be just what the OP had missed. – underscore_d Apr 22 '16 at 14:47
  • Possible duplicate of [Is it possible to declare a virtual static constant value in a C++ class?](http://stackoverflow.com/questions/10915568/is-it-possible-to-declare-a-virtual-static-constant-value-in-a-c-class) – Sneftel Apr 22 '16 at 15:16
  • @Sneftel It's not dublicated because I don't want any member to be declared in the inherited classes. I want somehow the constructor to do that. –  Apr 22 '16 at 15:19
  • "I want somehow the constructor to do that." Well, people have written answers that do this using constructors, plus other answers that use a different method but still don't require redeclaration in the inherited classes. Have you tried any of those? – underscore_d Apr 22 '16 at 15:30

4 Answers4

1

You could use a virtual function, something like this:

    class A
    {

        virtual int max_val() const = 0;

        protected:
        Uint _count;
        TVint _elemente;

        public:
        //
    };

    class B : public A
    {
        int max_val() const { return 42; }
    };


    if ( max_val() < _count ) ...
Rob K
  • 8,757
  • 2
  • 32
  • 36
  • This should be the default way to do this imo. Think of these getter functions as 'virtual variables' and it just makes sense. There are cases where `virtual`s aren't appropriate and it's better to `template` on the variable, but I think those are a relative minority. – underscore_d Apr 22 '16 at 15:13
1

Based on other comments it seems like you want a const number that is accessible in the base class which can have a different value depending on the derived class. You could achieve that like this: https://ideone.com/JC7z1P

output: A: 50 B: 80

#include <iostream>
using namespace std;

class Base
{
private:
    const int aNumber;
public:
    // CTOR
    Base( const int _aNumber ) :
        aNumber( _aNumber ) {}

    // check value  
    int getNumber() const
    {
        return aNumber;
    }
};

class A : public Base
{
public:
    A() : Base( 50 ) {}
};

class B : public Base
{
public:
    B() : Base( 80 ) {}
};

int main() {
    A a;
    B b;

    std::cout << "A: " << a.getNumber() << std::endl;
    std::cout << "B: " << b.getNumber() << std::endl;

    return 0;
}
RyanP
  • 1,898
  • 15
  • 20
  • As Alexander implied, if the value is to be the same for all instances, it's a bit bloat-y to make it a non-`static` member. That doesn't stop this from being a useful example, though! – underscore_d Apr 22 '16 at 15:10
  • 1
    There's a million ways to skin a cat. If you make it static and in the base class you can't make the value different for each derived class. If you make it static and in the derived class you can't access it directly from the base class without virtual functions. Also, depending on usage patterns, if it is a part of the class and not static, in small classes it will probably always be cache-hot instead of needing an additional load. – RyanP Apr 22 '16 at 15:19
  • Excellent points! Especially about caching, which in some situations is reason enough on its own. – underscore_d Apr 22 '16 at 15:22
0

When you write like

class B : public A
{
    const int MAX_VAL;
};

what value do you expect B's class instance to hold with current approach? Have you tried to add ctor to B (to initialize MAX_VAL to some exact value), so that whole class definition should be like

class B : public A
{
    const int MAX_VAL;
public:
    B(int max_val):MAX_VAL(max_val) {}
};

Also, the code above shows a lot of unanswered questions. Some of them:

  • Do you really need it to be member? mark it as 'static' (static const int MAX_VAL = 5) . That would mean, every B's instance MAX_VAL would be equal
  • All of type redifinitions don't look meaningful. What if you use intrisic types and auto?
  • Usually one doesn't compare size() with 0 - just calls empty().

Have you tried to read Stroustrup or Lippman?

  • Well, to be more clear: I have more inherited classes from A, let's say B, C, D and E. In all this classes, I have the MAX_VAL1; MAX_VAL2 etc. I want anyone of them to have a number, like MAX_VAL1 50, MAXVAL2 80 and so on. –  Apr 22 '16 at 14:41
  • @ReduClarely so, you really want a `static` variable for each class type, not each instance, as Alexander suspected. – underscore_d Apr 22 '16 at 14:46
  • @underscore_d Yes, I guess. DO you have any idea about how can I do that using a static variable for each class type? –  Apr 22 '16 at 14:51
  • @ReduClarely I've thought about this a bit more. `static` may or may not fit your situation. Do you want polymorphism? If so, since variables (whether member or static) cannot be virtual, you would need to do something like RobK suggested. In either case, both strategies should be well documented in any good tutorial. – underscore_d Apr 22 '16 at 14:58
  • Well, it doesn't matter if I use polymorphism or not in order to make it work. Let me tell something else. I have to delete all the members from the inherited classes and use _elemente (which is a vector) in order to initialize MAX_VAL1, MAX_VAL2 with actual values. –  Apr 22 '16 at 15:08
  • @ReduClarely Please add such information to your question, rather than here. – underscore_d Apr 22 '16 at 15:08
0

If you want to access it statically, you can do it by using templates :

  • ABase gives polymorphic access to value
  • A gives static access to value
  • B and Care examples of usage

.

// This is the polymorphic root class
class ABase
{
public:
    ABase(int maxV) : _maxV(maxV) {}
    int maxValue() { return _maxV; }
private:
    int _maxV;
};

// This class gives static method
template<int V_MaxValue>
class A : public ABase
{
public:
    A() : ABase(V_MaxValue) {}
    static int maxValue() { return V_MaxValue; }
};

class B : public A<42>
{
};

class C : public A<35>
{
};

// Static access (neex explicit class call) :
// B::maxValue() => 42
// C::maxValue() => 35
//
// Polymorphic call :
// ABase* poly = new B();
// poly->maxValue() => 42
56ka
  • 1,463
  • 1
  • 21
  • 37
  • Does this have any advantage over just using a regular `static` class variable or, if dynamic polymorphism is required, a vfunc? Not a trick question ;-) – underscore_d Apr 22 '16 at 15:00
  • Yes, if you define a static var in `A`, all its inherited classes will have the same value because it will be the same var. What to you mean by vfunc ? – 56ka Apr 22 '16 at 15:03
  • Great point! I personally default to using `virtual` getters where possible, as they in theory cover more situations - but, of course, there are cases were using `virtual`s is difficult or impossible (e.g. if standard-layout is required, or RTTI is disabled, or etc.) - so it can be very useful to 'bake in' such values using `template`s. It can get weighty if lots of methods use the template argument, since (in theory) each has to be instantiated separately with the different value hard-coded. But there are definitely uses for both patterns. – underscore_d Apr 22 '16 at 15:07
  • Of course, but virtual needs instanciation and I think he requires static access :) I've added polymorphic way to do it but it requires an extra layer (here called `ABase`) – 56ka Apr 22 '16 at 15:14