Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
Say that in file foo.h I have:
enum bar {
ONE = 1,
TWO
};
class foo {
bar m_bar;
public:
void setBar(bar arg){ m_bar = arg; }
bar getBar() const { return m_bar; }
};
In my current design, the only persistent bar variable will be m_bar. But I will have other functions, outside of foo that contain a bar, for example a GUI class that creates a local bar and passes it to setBar.
So here's my question, is there any rationale to defining bar publicly inside foo versus just inside the class where it is?
So here's my question, is there any rationale to defining bar inside foo versus just inside the class where it is?
If all the functions that create/work with bar are related to foo functionality, then it is perfectly acceptable to write it like this:
class foo
{
enum bar {
ONE = 1,
TWO
};
};
void process_bar_of_foo(foo::bar bar_value); // process the bar of a foo
If on the other hand you can write code that has (conceptually) nothing to do with a foo instance but deals with bar values, you should probably write it separately.
Well, as it stands, you can create bar objects with objects and functions outside of the foo class like you mentioned and then pass it to whatever foo object you make.
If you were to, however, define it in the class, then you wouldn't really be able to make bar objects unless you create a foo class first which can lead to unnecessary overhead if you just want to enum object.
And so it really depends on what you're going to do. If you only plan on using bar with the foo class, then it would be perfectly acceptable to define it there. Otherwise if it's going to be accessed elsewhere, leave it as is.
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
I would like to ask the proper location of typedef in C++.
Version1 : typedef outside class
typedef std::pair<std::string, int> StrIntPair;
typedef std::vector<StrIntPair> StrIntPairVec;
class MyData
{
public:
MyData(){};
~MyData(){};
private:
void addInfo(const StrIntPair &info)
{
infoVec.push_back(info);
}
StrIntPair info;
StrIntPairVec infoVec;
};
Version2 : typedef inside class public
class MyData
{
public:
MyData(){};
~MyData(){};
typedef std::pair<std::string, int> StrIntPair;
typedef std::vector<StrIntPair> StrIntPairVec;
private:
void addInfo(const StrIntPair &info)
{
infoVec.push_back(info);
}
StrIntPair info;
StrIntPairVec infoVec;
};
Version3 : typedef inside class private
class MyData
{
public:
MyData(){};
~MyData(){};
private:
typedef std::pair<std::string, int> StrIntPair;
typedef std::vector<StrIntPair> StrIntPairVec;
void addInfo(const StrIntPair &info)
{
infoVec.push_back(info);
}
StrIntPair info;
StrIntPairVec infoVec;
};
Which version is the best practice?
This depends on where you use the type alias. I'd advice you to
Put them outside of the class if you use them across classes and/or functions and the meaning of the alias is not exclusively related to the class.
Define them as public class type aliases if client code outside of the class needs to access them (e.g. to initialize the object or to store an aliased return value of a member function) but the alias is related to the class. The alias then becomes a part of the class interface.
Define them as private class type aliases when you use them exclusively inside the class, e.g. some utility data structure that is annoying to type out all the time when passing it across member functions.
The compiler will only enforce scopes of aliases that are too narrow (e.g. you use a type alias defined in the private section of your class outside of that class) and won't complain if you choose an unnecessarily permissive scope (e.g. you publicly declare the alias, but use it only in the class implementation). Hence, strive to choose the narrowest scope possible, which is in line with hiding implementation details.
As a side note, you might want to consider declaring your type aliases with using StrIntPair = std::pair<std::string, int>;, see Item 9 in Effective Modern C++. This has no influence on the above, though.
The question is about logical namespace of those names. With abstract naming like StrIntPair, StrIntPairVec and MyData there are no answers. Answers come when the things have meaning.
Lets take exactly same data structures but name them NickAndId, Friends and Player.
Now the question if to put NickAndId inside Player is about if it is specific to player. Can other entities like NonPlayerCharacter or Creature also have nickname and id expressed as same pair? Possibly. Then it should be outside.
Same question should be asked about Friends. Likely the NonPlayerCharacter and Creature can have nickname and id but do not have friends? Then it makes sense to put the type inside of Player as Player::Friends.
Finally, the types that are made private are meant only for usage by implementation details. That should be used when the name makes perfect sense in algorithms used inside of class but availability of those outside is unneeded or even worse, confusing. For example NonPlayerCharacter can react with some replicas to some states whose values are also internal to that NPC. Keeping that in sorted vector Reactions makes perfect sense inside of class. Access to ReplicaInState and Reactions from outside can be confusing.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I read about defining a struct like:
struct someStruct {
int x;
int y;
};
struct otherStruct : public someStruct {};
So my question is about the definition of otherStruct.
What does this definition do?
I'm new in C++ so i only want to know under which key word i can find the definition of otherStruct to read about them in a book.
This answer is just a scratch on the surface of the inheritance concept of OOP and it does not cover all its aspects. You should read a book about C++ (or about OOP in general) to get a complete answer.
The part struct otherStruct : public someStruct says that otherStruct extends someStruct with public inheritance. In simple words, public inheritance does not change the visibility of the members (properties and methods) inherited from the base class.
The declaration block of the new struct ({}) is empty. It does not add any new members to those inherited from struct someStruct.
If you compare someStruct and otherStruct by their memory footprint and behaviour, they are identical. But they are different types and they cannot be replaced one for the other.
However, a pointer to a variable of type otherStruct can be used where a pointer to struct someStruct is expected (because otherStruct, by extending someStruct has all the properties expected from someStruct) but the other way around is not possible.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
How to Interpret the name of class in following piece of C++ code ?
Following code is part of a project which is compiling successfully with g++ compiler.
class ABC::DEF
{
public :
int a;
void func();
};
void ABC::DEF::func() { a = 3; }
ABC::ABC() : OBJ(new DEF())
{
}
ABC::~ABC()
{
delete OBJ;
}
How to interpret ABC,DEF and OBJ in the above code?
How the constructor defined above works ?
The definition of ABC most likely looks something like this:
class ABC
{
public:
ABC();
~ABC();
private:
class DEF;
DEF* OBJ;
};
and what you're looking at is the definition of the class ABC::DEF and the constructors of ABC.
(This is a quite normal way of implementing the "pimpl idiom".)
ABC::DEF is a nested class. If you look at the definition for class ABC, you should see a forward declaration of class DEF. You can give the full definition for such a class outside of the outer class as shown in your question.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
Since C++11 we can default construct our variables in a class, like this:
class Foo{
private:
int bar = 0;
};
I've very rarely seen someone using this feature
Is this a good practice ?
This is a style question, but there are some considerations that are hopefully universal:
If all constructors of your class have to initialize a member the same way, because the initial value is in some profound way part of the invariants of the class, then it is both more readable and self-documenting and also shorter to use the inline initializer, and the deduplication removes a source of errors if you ever need to change the initial value.
Otherwise, if different constructors supply different initial values, then you shouldn't have an inline initializer, even though that's technically permitted.
I dont see any bad practices in this approach. This is allowed even in Higher level languages like Java. It reduces lines of code inside constructor.
The only big disadvantage I see is that it may lead people to expose more implementation details than necessary in class definitions. Currently, if you initialize a member in MyClass.cpp, then you can easily change the value later on. If you initialize the member in MyClass.h, then a lot of recompilation could be necessary if you later change the value.
In Java, you don't have this kind of separation between header and implementation, so the situation cannot be compared to C++.
C++11 allows non-static data members to be initialized in-class.
This can often save some typing. Consider the following example:
class Foo {
public:
Foo() : a_{5}, b_{7}, s_{"Foo"}, bar_{"Test"} {}
Foo(int x) : a_{x}, b_{7}, s_{"Foo"}, bar_{"Test"} {}
Foo(double d) : a_{5}, b_{g(d)}, s_{"Foo"}, bar_{"Test"} {}
int someFunc();
private:
int a_;
int b_;
std::string s_;
Bar bar_;
};
Using in-class initialization will IMHO make the code more readable.
class Foo {
public:
Foo() = default;
Foo(int x) : a_{x} {} // Initialization list overrides in-class initialization.
Foo(double d) : b_{g(d)} {} // Same here.
int someFunc();
private:
int a_ = 5;
int b_ = 7;
std::string s_{"Foo"};
Bar bar_{"Test"};
};
I would say use it when possible. An exception is when the situation described in this answer applies.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
Say for example I have two classes.
I know that one way is to pass a pointer to the Foo object in the constructor and then use that inside Object, but is this a good way to approach things?
Is there something else more appropriate?
Thanks.
class Object
{
private: //etc
public:
void doStuff()
{
//access the foo object (x) created in main.
}
};
class Foo
{
private: //etc
public:
void function()
{
Object * obj = new Object();
obj->doStuff();
}
};
int main(int args, char**argv)
{
Foo * x = new Foo();
x->function();
return 0;
}
It depends on what you have to do.
If your doStuff() method must know the content of the given object you can't use this way. Otherwise, if you, like in the example you post, your doStuff method has just to create an object for performing an internal operation you may use this approach.
Generally, there is not a better or a worse way of operating. It always depends.
An example.
Your doStuff method needs something from the external in order to do something:
class Foo
{
private: //etc
public:
void function(Object* obj)
{
obj->doStuffWithTheGivenObject();
}
};
}
Your doStuff method needs nothing from external:
class Foo
{
private: //etc
public:
void function()
{
Object* obj = new Object();
obj->doStuffModifyingTheGivenObject();
this->doStuffOnThisFooObjectWithTheJustCreatedObject(obj);
}
};
}
In the second case your Foo object does not need an Object, because it can independetly create an object by itself for using it internally.
In the first case, instead, it is waiting for an Object because it uses that one for doing something.
The difference stays in: "Do I need an object or I can create that internally?"
It might help here to know what "Foo" and "Object" actually are. If "Object" actually is "Fruit" and "Foo" is an "Apple" than inheritance makes sense. Alternatively if "Object" represents some sort of stream and "Foo" represents a class that depends on the stream, then what you are doing makes sense. Its all going to depend on what you are trying to accomplish here.