If you have a class that has some named constants, what is the best practive for storing the constants:
Option 1: Namespace in Class header
So in my class header I will have:
class myClass
{
...
...
};
namespace NamedConstants
{
const string Bucket = "Bucket";
}
Option 2 Member Constants
class MyClass { // this goes in the class
private: // header file
static const string Bucket;
...
};
... and in the class implementation file:
const string MyClass::Bucket = "Bucket";
I actually prefer Option 1, considering it to be cleaner: the variable name and value appear together. Also, if you give the namespace a good name then it can make code more readable when you use constants:
TrafficLight::Green
Does anybody see any issue with this method over Option 2?
If the strings are meant to be seen/used by users of the class, you wouldn't consider to make them private class members. So I conclude they are not meant to be seen/used by users of the class. But then it doesn't make sense to put them into the header at all.
If you put them into the class (or into namespace scope into the header), then all changes to their type and identifier will force clients to recompile their code.
If you put them into the class' implementation file, they are a private detail of the class' implementation and changes to them only force recompilation of the class' implementation.
If you put them into an unnamed namespace, they cannot collide with any other name:
namespace {
namespace NamedConstants
{
const string Bucket = "Bucket";
}
}
Option 1 could lead to a separate string object for every file which includes the header. So it depends among others on how scarce your resources are.
Related
I want to use type alias to shorten the long names of
parameters to member-functions within my class.
The parameters can be of type: std::vector<std::shared_ptr<T>>
I want to know, if adding private aliases inside a class in the header file, is safe for a library? Is it a bad practice? then why and what kind of errors can it lead to?
Given that this header will get included by all kinds of libraries and projects.
Here is an example:
// A.h. - will get included by other libraries
namespace mylib::module
{
class A
{
// type aliases - private to A
using str = std::string;
using strings = std::vector<std::shared_ptr<str>;
public:
// public interface
void funcA( str a);
bool funcB( strings strs);
}
}
Note: that this is not a question about namespace aliases.
I am strictly speaking of type-aliases which will become the parameters to public functions.
For constants of a class, should I use class scope static const, or file scope const?
For example:
// .h
class C {
private:
static const int some_constant_c;
}
// .cc
const C::some_constant_c = 10;
vs.
// .h
class C {
}
// .cc
const some_constant_c = 10;
To me, the former one have better semantic meaning that the constant is of a certain class, but the latter one have the advantage not exposing constants to header file.
==============
One follow up question on this:
What if I want my constants be accessed by subclasses. Make sense to put static const in protected? Example follows:
// .h
class C {
protected:
static const int some_constant_c;
}
It's a matter of personal preference, of course. Trying not to expose class internals in the header file is a ship that has most definitely sailed in C++... between member variables and private member functions, it's just not practical to keep implementation details out of the header (unless you're using the pImpl idiom).
If all you want is to hide the value of the constant, note that you can put the initializer in the source file instead.
If you do implement the constants as globals in the source file, use an anonymous namespace to keep them from causing linker collisions.
I'd prefer 2nd variant, provided the const in the 1st case is private.
Why should one pollute the class declaration with redundant information?
Consider, you are implementing a protocol parser, with many many constants. How will the class declaration look like?
Another issue is, why should you type the name of the const twice? I try to keep definition and initialization as close as possible.
Just an opinion.
I have functions stored with a class in a header file that I #include in the header of my Source.cpp file. The header contains a date class, along with relevant constructors, overloaded operators, and methods.
I leverage these functions in some of my class' constructors (for instance, a function to convert a Gregorian calendar day into a Julian day number). However, I can't think of a valid reason to allow the use of a few of these functions outside of the header file: they're only useful to the class, after all.
Is there a way for me to make it impossible for these functions to be called outside of the header file, short of making them private methods of my class?
EDIT: Would the solution also apply to other entities in the class, like structs?
What you are trying to achieve is materially difficult given the nature of header files in C++. Normally you hide internal details in a nested, anonymous namespace, however that would still be visible to callers who import your .h file. Thus you only use this trick inside of your .cpp file to make private, non-exported symbols.
The correct thing to do is to place these private class implementations and the implementation of your constructor inside of your .cpp file.
// foo.h
namespace fooproject {
class Foo {
public:
Foo(::string s);
private:
int converted_s; // Will be derived from constructor input
}
And then:
// foo.cpp
namespace {
// Everything here is visible to this compilation unit only.
int SecretMagicConverter(::string s) {
// magic code
}
} // namespace
namespace foo_project {
Foo::Foo(::string s) {
// Here we can plainly call the anonymous namespaced functions above.
converted_s = SecretMagicConverter(s);
}
} // namespace foo_project
Regarding your follow up, yes, anything in that anonymous namespace is 'normally' usable inside of that .cpp but hidden from any users of your .h file.
Is there any reason why one shouldn't #include another file from within a class declaration when that class defines numerous private constants?
I'm writing a class which adheres to a simple state-transition system and defines a processing schedule consisting of several states, each of which consist of a series of steps. Because the class has to refer to these states and steps in various functions (for example, when determining which processing to apply based on the current state and step), I end up defining a bunch of private enum's within the class's declaration to make the implementation readable (so I can refer to things like kStates_ModeTransition and kStateSteps_ModeTransition_PrepareNewSetup etc, rather than just using the raw integer values associated with these states and steps).
As the list of states and state-steps has grown longer, this collection of enum's has become a fairly long, awkward chunk of code in the middle of the class declaration, and I feel these constants are more connected to the implementation than the interface - a user of the class doesn't necessarily have to know about them. Is there any reason why I shouldn't move all of these enum's to another file and then just #include that file into the private section of the class declaration? I haven't encountered another situation where it seemed appropriate to use a #include within the body of a class, so I'm wondering if there's a better way to handle this or any particular reason such an #include would be bad form. Furthermore, is there any sensible standard file extension to use on such a file, used only for text insertion (it isn't really a header...)? Just .txt?
Thanks!
Edit: A bit more to see if one of the mentioned alternatives completely dissolves my dilemma:
Trying to stick only to the essentials, here's an example of my current structure
// Processor.h
class Processor
{
public:
Processor();
void Process( float* input, float* output, int numSamples );
private:
// List of possible states
enum
{
kStates_Default,
kStates_SettingChangeImmediate,
kStates_SettingChangeCrossfade,
kStates_SpecialProcessing,
kStates_NumStates
};
// Lists of steps for each state...
enum
{
kStateSteps_Default_PrepareInput,
kStateSteps_Default_CalculateIntermediateValues,
kStateSteps_Default_CalculateOutput,
kStateSteps_Default_NumSteps
};
// Imagine more lists for other states here, with comments...
// Becoming quite long...
// Private functions used in implementing various processing steps
// (some are used by multiple state-steps in varying ways)
void PrivateFunction1();
void PrivateFunction2();
// Some member variables here
};
This is used in a real-time processing context in order to better balance DSP load when performing block-processing tasks. In reality, this class inherits from a base class which handles the actual scheduling of calls to Process, updating the current state and state-step as needed. Process() then consists of a switch statement which performs certain processing functions and IO based on the current state and state-step of the object.
The values declared in the enums are used within Process() and other private member functions inside processor.cpp, and nowhere else. I've declared them as private member variables to scope them to within the class. Is there a way to declare them inside the .cpp and achieve the same scoping? These are all meant to be constant integers optimized away at compile time and are essentially being used as #define 's - I just don't want to use macros.
All includes are just text inclusion. Since the file you're including contains C++ syntax, it should have a C++ header extension (.h or .hpp or etc.).
You may not need to include it into the declaration (I could speak to this more certainly if you post some code) ... you could just include it into the implementation files, and declare any enum member variables as int ... using typedefs (aliases for int) if you want to give them descriptive type names. Or if you're using C++11, you can forward declare your enum types without defining them, and then you enum member variables will be typesafe, preventing assignment of the wrong sort of enum value.
As for your question of whether there's a reason why you shouldn't move the enums out of your class declaration into another file and include that file: one can always invent reasons not to do things, such as "our Coding Standards say never to include a file other than at top level, at the top of the file", but if such arbitrary reasons don't apply to you then no, there's no reason. Do what makes the most sense in terms of code maintainability.
Using an #include in the middle of a class is highly irregular and could cause problems. It's much better if you declare your constants in either their own namespace or class.
For instance, this is a bad idea:
class Foo
{
#include "foostuff.h"
};
The more typical pattern is:
#include "foostuff.h"
class Foo
{
void bar(int x = FooStuff::const_x);
};
Inside foostuff.h you'd be careful to namespace things so they won't collide with other parts of your application.
The C++ way of doing things encourages the re-use of constants between different parts of your application instead of using #define to create macros that, once expanded, have no particular association.
All "include" files should be either .h for plain C or .hpp for anything that requires a C++ capable compiler to interpret. Anything else is non-standard and will, at the very least, lead to scorn from anyone who has to maintain your code.
New C++11 enum class may be forward declared and real definition moved to implementation. That will clean the mess and reduce annoyance.
// Procesor.hpp
class Processor
{
public:
Processor();
void Process( float* input, float* output, int numSamples );
private:
// Type of possible states
enum class kState;
kState somethingDealingWithState( kState s );
};
// Processor.cpp
// List of possible states
enum class Processor::kState
{
Default,
SettingChangeImmediate,
SettingChangeCrossfade,
SpecialProcessing,
NumStates
};
Processor::kState Processor::somethingDealingWithState( kState s )
{
if ( s == kState::Default )
{
return kState::SpecialProcessing;
}
return kState::Default;
}
In the end, it seems the best way to achieve equivalent functionality while gaining the benefit of separating the enumeration details into the .cpp implementation file is to use a forward declaration of a struct within the private portion of the class, and to then define that struct to contain the desired enum's from within the .cpp file.
// Processor.h
class Processor
{
public:
Processor();
void Process( float* input, float* output, int numSamples );
private:
struct States; // Used to scope State enum to within class
struct StateSteps; // Used to scope StateStep enums to within class
// Other stuff...
}
// Processor.cpp
struct Processor::States
{
enum
{
Default,
SettingChangeImmediate,
SettingChangeCrossfade,
SpecialProcessing,
NumStates
};
}
struct Processor::StateSteps
{
enum
{
Default_PrepareInput,
Default_CalculateIntermediateValues,
Default_CalculateOutput,
Default_NumSteps
};
enum
{
SettingChangeImmediate_FirstStep,
// ... other state-steps...
};
};
Here's why I think this structure is best in this particular use-case:
All enum listings are moved to the .cpp file, out of the middle of the header as desired, and additional StateStep enums which contain the same values (say, counting up from 0) may be added into the definition of the StateSteps struct without disturbing the .h header (while we could add entries to a forward-declared enum class, we couldn't have repeats of the same value and would need to add another enum class to the header).
All of the enums are scoped within the private portion of the class as before (albeit within another struct as well).
Enums which are being used to define compile-time integer constants may remain anonymous and not strongly typed enum class constructs, which may mislead others as to how the enums are being used (in the current use-case, we WANT to be able to compare different stateStep enum values to the same integer currentStep, depending on the current state, as we could with the originally defined anonymous enums).
Previous answers helped get me to this conclusion, but I feel that this is a way which most closely duplicates the functionality of the original definitions while moving them out of the .h file!
I have a program that uses enum types.
enum Type{a,b,};
class A
{
//use Type
};
class B
{
// also use that Type
};
2 class are located in 2 different files.
Should I put the type definition in a headfile or
in class definition for each class?
If the enum is going to be used in more than one .cpp file, you should put it in a header file that will be included by each. If there's a common header file, you should use that, otherwise you may as well create a new header file for this enum
You should always attempt to limit the scope of types in C++, so the enum should probably be declaread at class scope. The enum will typically belong slightly more naturally in one class than the other - lets say class A, so you put it in the declaration of A in the a.h header:
// a.h
class A {
public:
enum Type { a, b };
...
};
Now you need to include a.h in the header that declares B:
// b.h
#include "a.h"
class B {
public:
void f( A::Type t ); // use the Type enum
...
};
I can see the point of Neil: it is a pet peeve for many programmers to see stuff on the global scope. otoh, imho, introducing a class just for an enum is not a good style: It is supposed to be enum not a class. However, putting the same enum list in both classes (is what you were asking) would be the worst idea: we don't want to be repeating stuff.
Moreover, in most non-trivial codes, one might end up using more of such shared entities (more enums, const parameters, etc...) for implementation. So, I'd begin lumping all this into an implementation namespace (say "detail") which is a child namespace of your classes, and resides in a separate header file (say "detail.hpp"), included by all. For example:
// file A.hpp
#include "foo/detail.hpp"
namespace foo {
class A
{
// accessing enum as detail::a
};
}
// file B.hpp
#include "foo/detail.hpp"
namespace foo { class B { ... }; }
// file foo/detail.hpp
namespace foo { namespace detail {
enum { a,b, ... }
const int three = 3;
// etc...
// other implementation classes etc...
}}
And "detail" is nice and clean way of warning your class users to back off from whatever's declared in there. As your code gets bigger and these implementation details start growing in number you can break the dependencies into separate header files (detail1 detail2 etc...) and still keep one "detail" namespace (something which you can not do with a "class detail" for example).
The question is rather vague, but as a rule of thumb, you should try to minimize the redundancy in your code. Therefore, you should put the declaration of the enum to a header file.
It really depends on if the values are the same logical type, or if they just happen to have the same names. Would it make sense to assign an A::Type variable to a C::Type? If they are the same logical type, put them in a header that both include. To keep your build times low you probably want to put it in its own header file, but putting it in a shared header with other stuff works if you want to keep the number of files down.
Another option is to put the enum in a common base class that both inherit from (this may not make sense in this case, but it is another option).