How can I have class within struct - c++

I have a class..
class myClass
{
public:
myClass(int time);
}
Then I need to have this class within struct.
class TopClass
{
public:
typedef struct{
int myint;
myClass myclass;
}tStruct;
tStruct sStruct1;
tStruct sStruct2;
}
How can I do it? How can I call constructors for myClass?
Is only way to use class instead of struct?
My constructor
TopClass::TopClass():
sStruct1({32, myClass(100)}),
sStruct2({52, myClass(1000)})
{
}
But I am getting error:
extended initializer lists only available with -std=c++0x or -std=gnu++0x

You can add constructor to struct: http://ideone.com/ifBw2
class TopClass
{
public:
struct tStruct {
tStruct(int time, int k = 0): myint(k), myclass(time) {}
int myint;
myClass myclass;
};
TopClass(int t): sStruct1(t), sStruct2(t) {}
tStruct sStruct1;
tStruct sStruct2;
};
Edit
As for new question - you have to use new standard (-std=c++0x) to do that this way. In old standard you have to add explicit ctor to initialize member variables. struct in C++ is nearly exactly the same as class - you can add ctors, member functions, static functions. The only difference is default privacy - public for struct and private for class:
class A {
public:
int b;
};
is exactly the same as
struct A {
int b;
};

How can I do it? How can I call constructors for myClass?
Your struct will need a constructor, since it has a member with no default constructor. In order to have a constructor, it will also need its own name, not just a typedef alias.
struct tStruct {
// If you want a default constructor:
tStruct() : myClass(42) {}
// If you want to specify the time:
tStruct(int time) : myClass(time) {}
int myint;
myClass myclass;
};
Is only way to use class instead of struct?
class and struct mean exactly the same thing (apart from the minor distinction of having different default access specifiers). Anything you can do with one, you can do with the other.

Actually, Pawel Zubrycki’s answer is all right.
But I want to know why you have to do in this way that you have to import another class constructor inside TopClass.
I mean that the code should follow the rule of high cohesion and low coupling.
In software construction we’d rather prefer the composition (an important design mode) to a class defination in it. Something like the following code.
class B{
public:
B(int y){b = y;}
private:
int b;
};
class A {
public:
A(int x):b(x){...};
private:
B b;
};
From the code we can maximize class B and obviously reduce the complexity of class A. A & B can change all by themselves.

Related

Can I inherit a constructor in C++11 and initialise something extra without having to rewrite the constructor?

I was happy to find out that in C++11 we can inherit constructors like:
class Foo
{public:
Foo(int a, double b, std::string name, char somethingElse);
};
class Derived : public Foo
{public:
using Foo::Foo;
};
But I'm finding that I'm often extending the base class where there might be maybe one or two extra features, and I need to initialise a couple extra members by maybe passing as extra argument or something. In this case is seems I have to rewrite the constructor and pass all the arguments to the base one. I'm wondering if there is a better solution. I thought maybe just using the inherited constructor and then initialising the extra member on the next line after construction, but it doesn't seem right:
Derived d = Derived(6, 6.0, "name", 'a');
d.extraMember = 4;
d.funcptr = &somefunction;
I figured it was an excellent feature but then I realised more and more that my extended classes needed extra initialisation info.
Here's my example from my code:
struct Window
{
Window(Window* parent, vec2 position, vec2 size, const String& name);
};
struct ConsoleWindow : Window
{
using Window::Window;
// But I've had to rewrite the constructor again because in this constructor I do stuff like
//GUI::bIsConsoleWindowActive = true;
//GUI::unselectWindow();
//GUI::selectedWindow = this;
}
It seems to me you can't add extra things to the construction process without rewriting the constructor and calling the base and passing all the values. This is common throughout my classes.
If your base classes are copyable/moveable and not abstract, you can push the burden of constructing the base class onto the declaration of the derived object. Just accept a base object:
Derived(Base b, int extraMember) :
Base(std::move(b)), extraMember(extraMember)
{
}
Where the declaration becomes this
Derived d{Base{6, 6.0, "name", 'a'}, 4};
That isn't perfect either, since it places certain requirements on your base classes that may not hold. And if it looks like aggregate initialization to you, then that's because this sets out to mimic it.
I'm afraid the only way that can definitely be adapted to any situation, is to spell out a new c'tor like you do now.
It wasn't clear from your question if you are able to change the base class. Assuming you are, you might consider packaging up your base constructor arguments into a struct, which could be forwarded up from the derived constructor.
This is often seen when implementing the builder design pattern, which is one way to solve the telescoping constructor anti-pattern you're describing.
struct FooParts {
int i;
double d;
string s;
char c;
};
class Foo {
public:
Foo(FooParts const & parts) : parts(parts) {}
private:
FooParts parts;
};
class Derived : public Foo {
public:
Derived(FooParts const & parts, bool extra) : Base(parts), member(extra) {}
private:
bool member;
};
I'm not sure, from your question, if you realize that you can call the base constructor from your derived constructor. Using your example:
struct Window
{
Window(Window* parent, vec2 position, vec2 size, const String& name);
};
struct ConsoleWindow : Window
{
ConsoleWindow(Window* parent, vec2 position, vec2 size, const String& name, int otherValue)
: Window(parent, position, size, name)
{
// do something with `otherValue` here.
}
};
See for example here: calling the base class constructor in the derived class constructor
The most straightforward way to do what you described is to use the base class constructor in the initialization list of the derived class:
class Foo
{public:
Foo(int a, double b, std::string name, char somethingElse);
};
class Derived : public Foo
{
public:
Derived::Derived(int a, double b, std::string name, char somethingElse,
int _extraMember, char derivedSpecificThing) :
// Initialization list starts here
Foo(a, b, name, somethingElse),
extraMember(_extraMember)
{
// Do something with derivedSpecificThing etc.
}
private:
const int extraMember;
};
using Foo::Foo only exposes the constructor of the base class as an additional constructor for your derived class. Of course, the constructor of the base class cannot initialize the additional members of the derived class that it knows nothing about.

Is this duplication in constructors with initializer lists really necessary?

Am I using initializer lists correctly in my class? There seems to be a lot of code duplication. If I needed another variable, I'd have to add it in three places.
class MyClass {
public:
MyClass(
anotherClass _a,
std::string _b,
std::string _c,
float _d
)
: a(_a),
b(_b),
c(_c),
d(_d)
{ }
private:
anotherClass a;
std::string b;
std::string c;
float d;
};
The usage of initializer lists is correct but it's pretty dubious as to what the point of this class is. You could just make all the members public and then use aggregate or uniform initialization to initialize each member. If you actually need not-shown complex semantics, then there is nothing wrong with this use of init lists.
If you end up having a class, that
1) Have a constructor sending in all its data,
2) have getters for all members and
3) have setters for all members,
you should probably go for a struct with no private members.
Then you can use 'uniform initialization' like:
MyX x{"hello",5.5};
Without having to write a constructor.
If this is not the case (your class actually have an invariant) then
yes, you have to add a thing in 3 places when adding a member.
Note, that due to scope rules, the following works:
class A {
int mem;
public:
A(int mem) : mem(mem) {}
};
no underscore needed.

C++: writing a function for a struct outside that struct? [duplicate]

This question already has answers here:
What are the differences between struct and class in C++?
(30 answers)
Closed 8 years ago.
For classes, you could just say:
class Test{
int a;
Test(int a);
}
Test::Test(int a) {
this->a=a;
}
Function names get "classname::" in front of them when declared outside of class.
How would I do this for structs?
struct Test {
int a;
Test(int a);
}
How would I write the function for this struct Test outside of struct declaration so that it can be only be called by a Test struct?
Same way. Difference between struct and class in C++ is only default visibility of members (private for class, public for struct).
Actually, it's not just function, it's constructor of class/struct Test.
In C++, structs are essentially the same as classes except for their default protection levels: classes default to private, structs to public. To define that function outside of the struct so that it can only be called from a member, declare it as private, then define it as normal:
struct Test {
private:
int a;
Test(int a);
};
Test::Test(int a) {
this->a=a;
}
Additionally, instead of modifying the a member in the constructor body like that, you should use an initializer list. This sets the value of the member before the instance is fully constructed. It's not so important with just an int, but it's a good practice to get in to.
struct Test {
private:
Test(int a) : a(a) {}
int a;
};
How would I write the function for this struct Test outside of struct declaration
Do exactly what you did for the first one. Both are class types, whether you use the class or struct keyword to introduce them.
The only difference is the default accessibility of members and base classes: private if you use class, and public if you use struct.
so that it can be only be called by a Test struct?
If you mean that you want it to be private (as it is in the first example), then you'll have to do so explicitly, since accessibility defaults to public:
struct Test {
int a;
private:
Test(int a);
};
Personally, I'd use the more conventional class if there's anything non-public.
ForEveR is right. Just like in the question you can have a structure member defined like:
struct Test{
int a;
Test(int a);
};
Test::Test(int a) {
this->a=a;
}
point to note, struct members are public by default. class memebers are private by default.

Strategy on how to share parameters between an object and one of its members

I would like to ask what is the "best" way to share a parameter between an object and one of its members. I try to explain better my problem: I have a class A which needs a specific a parameter to be defined:
class A
{
public:
A(int);
~A();
private:
int ParameterA;
...
}
Also I have a second class B which contains an object of class A as its member and needs another parameter to be defined:
class B
{
public:
B(int);
~B();
private:
A MemberA;
int ParameterB;
...
}
Now my question is: if ParameterA and ParameterB are always equal, what is the "best" (clean) strategy to use?
I thought of three possibility
First option is to have two copies of the same value saved with
different names as in the code above. This seems to me quite
"dangerous", it would force me to always check that the two values
are equals.
Declare public the ParameterA, so class B can access it
Define a get function so class B can access ParameterA using the get function
Is there any other (better/standard) approach to deal with this case? What method should I follow?
You could declare ParameterA as a reference, and intialize it to reference ParameterB.
class A
{
public:
A(int& val) : ParameterA(val) {}
~A(){}
private:
int& ParameterA;
};
class B
{
public:
B(int val) : ParameterB(val), MemberA(ParameterB) {}
~B(){}
private:
int ParameterB;
A MemberA;
};
Your intuition about the danger of having two variables always holding the same value is right: this is at the very least a code smell and should be avoided.
The straightforward solution is inheritance:
class A {
public:
A(int a) : parameterA(a) {}
protected:
int parameterA;
};
class B : public A {
public:
B(int a) : A(a) {}
};
Of course, it depends on the context whether this solution is advisable, but it should always be the first to be evaluated.
The "best" way will probably depend on how A and B are used.
Of your options, I would avoid 1 and 2 if you can but I think 3 might be a reasonable option unless the parameter is really not something you want to expose. If you want to keep the parameter private you could make B a friend of A.
Another option is to take the ownership of the parameter away from A. You could define the parameter outside the class (maybe inside another class) and pass a reference or pointer into B and A.
A more flexible approach might be to use a shared pointer but you might not need that flexibility in practice. By using a shared_ptr you do not restrict what you can do with your classes like references would and it doesn't tie the lifetime of A or B to the lifetime of an external object. And can easily create a self contained A on its own if you want:
#include <memory>
using SharedInt = std::shared_ptr<int>;
class A {
public:
A(SharedInt parameter) : parameter_(parameter) {}
private:
SharedInt parameter_;
};
class B {
public:
B(SharedInt parameter) : a_(parameter), parameter_(parameter) {}
private:
A a_;
SharedInt parameter_;
};
int main() {
auto b = B(std::make_shared<int>(3));
auto a = A(std::make_shared<int>(7));
}
But I might be tempted to go for a more restrictive design first and only move to shared pointers if needed.

class member needs this-pointer at instance-initialization

I was trying to create a member (prop of class A) to a class (B). This member "prop" of class A needs to gets the "this" pointer of the newly created B-instance passed in its constructor. Just as shown in the snippet (Snippet 1) below.
However, this is failing at compile time with the error message:
"A typespecifier was expected" (translated from german).
I think this is about I am not able to use the this-pointer in this context, but I do not want to go the way of Snippet 2 and use a pointer. It is just not practical for me.
Is there any way to accomplish this close to the coding style of the first snippet?
Snippet 1
class B;
class A
{
public:
A(B* b)
{
// ...
};
};
class B
{
public:
A prop(this);
};
Snippet 2
class B;
class A
{
public:
A(B* b)
{
// ...
};
};
class B
{
public:
B()
{
this->prop = new A(this);
}
A* prop;
};
Edit: Just figured out this snippet, but when having many of them in one class makes it really unreadable.
Snippet 3
class B;
class A
{
public:
A(B* b)
{
// ...
};
};
class B
{
public:
B() : prop(this) {};
A prop;
};
Many thanks!
Sebastian
You cannot initialize class member in class declaration. As you correctly noted in snippet #3 - constructor initialization list exists for the members, that require parameters to be passed to constructor.
Using an initializtion list is the best way IMHO of doing this, note, members are initialized in the order you declare them, but not the order at initializer list:
class B
{
public:
B() : prop(this) {};
A prop;
};
I got the solution by myself now.
For non-experimental; non-c++11 standard, luri Covalisin is right.
But if we give a look at c++11, we can do as follows:
class B;
class A
{
public:
A(B* b)
{
// ...
};
};
class B
{
public:
A prop{this};
};
this looks kinda weird, but is more like what I was looking for.