1

I'm a beginner in c++ with some Java background. I came cross this piece of sample code

class simple_cbuf { 
public:
    enum { default_size = 100; };
    explicit simple_cbuf(size_t size =
                         default_size);
    ~simple_cbuf();
    size_t size() const;
    bool   empty() const;
    int    top() const; /* see below */
    void   pop();
    void   push(int new_value);
  private:
    /* whatever you want */
};

It seems to me that this code is using a public enum to hold the default size of the buffer. Is it a common practice in c++? In Java I would make this a "private static final int" constant

TheInvisibleFist
  • 445
  • 1
  • 6
  • 12
  • Meh, that's just a coding style / personal preference thing. It certainly could be a `static const int` somewhere. – Cory Kramer Dec 29 '14 at 20:09
  • 1
    Or the default value could just be mentoned as the default argument directly. – Deduplicator Dec 29 '14 at 20:10
  • 1
    The nice thing about unnamed, unscoped enums is that they are guaranteed to take no space, and never requires a separate definition. (If it is a `static const int` and you pass it to a function taking a `const int &`, that counts as an odr-use and you need a definition; if it's an unscoped enumerator the compiler will just initialize a temporary `int` for that.) – T.C. Dec 29 '14 at 20:14
  • @T.C. Thanks for the explanation! But I don't get why unnamed, unscoped enums takes no space? – TheInvisibleFist Dec 29 '14 at 20:47

4 Answers4

1

It's a fairly common practice, to make sure a constant is really treated as a constant in all cases.

What C++ has a lot, that Java doesn't, is references to any type, even primitive types, and as a result of that,

struct S {
  static const int i = 3;
};
void f(const int &);
void g() { f(S::i); };

doesn't behave like how many want it to behave: it doesn't take the value of S::i, store that in a temporary object, and pass that object to f. Instead, passes a reference directly to S::i straight to f.

This sounds good, but can cause surprising problems where you wouldn't realise you really need a definition of S::i, to make sure its address can be resolved.

enum avoids that: after enum { i = 3 };, i is an rvalue, and its address cannot be taken. f(i); would be valid, and would pass a temporary object to f.

0

In c++ static const int is equivalent to static final int in java . If you use c++11, it can be static constexpr int to make sure a constant is always treated as a constant.

Enum is better when you have a few related values.

Piotr Siupa
  • 3,929
  • 2
  • 29
  • 65
0

Since size() returns a size_t, for consistency, you can do something like this:

size_t default_size() const noexcept
{
   return 100;
}
0
class simple_cbuf { 
public:
    enum { 
           default_size = 100, 
           expanded_size = 150,
           abridged_size = 50
    };
    explicit simple_cbuf(size_t size =
                     default_size);
    ~simple_cbuf();
    size_t size() const;
    bool   empty() const;
    int    top() const; /* see below */
    void   pop();
    void   push(int new_value);
private:
    /* whatever you want */
};

This code could be an example of why you would want to use an enum, and that private static final int can directly relate to static const int. The case you described isn't usual, but works.

Orange Mushroom
  • 431
  • 4
  • 16