How to assign the end of a reference chain? - c++

For example I have a class:
class Foo {
public:
Foo(const Foo& foo) : father(foo) {}
private:
const Foo& father;
};
How to assign the father field if the object is the top?
I tried Foo foo(foo);, but the compiler warn me the foo is uninitialized, I guess the compiler only assign memory to the foo object after all initialization are done, so if I do this way, the father will reference to some wild memory address.
So, In this case, how to assign the father right if the object is the top?

Use a special constructor (and use a tag to distinguish your constructor from the copy constructor):
struct father_tag {};
class Foo {
public:
Foo(const Foo& foo, father_tag) : father(foo) {}
Foo() : father(*this) {}
private:
const Foo& father;
};
// usage:
Foo father;
Foo next(father, father_tag{});
or you can use a pointer instead of a reference, leaving it to nullptr at the end of the chain. Then you can check with if (father) if you are at the end or not:
class Foo {
public:
Foo(Foo const* pfather) : m_pfather(pfather) {}
Foo() : m_pfather(nullptr) {}
private:
Foo const* m_pfather;
};

Related

Is const reference to a global constant good practice?

Trying to figure out how to efficiently and safely reference global custom type constants that are initialized at compile time. I want to avoid copying of Foo as I will be creating a lot of Bar instances and Foo is a bit more complicated than shown here. Keeping a const reference from Bar to Foo appears to be safe (or is it?) but at the same time I don't know how to prevent the "badBar" usage if possible. Any suggestions?
class Foo
{
int a_, b_;
public:
constexpr Foo(int a, int b) : a_(a), b_(b) {}
};
inline constexpr Foo kFoo{1, 2};
class Bar
{
const Foo& foo_;
public:
Bar(const Foo& foo) : foo_(foo) {}
const Foo& foo() { return foo_; }
};
int main() {
Bar goodBar(kFoo);
Bar badBar(Foo(3, 4)); // ouch
return 0;
}
Yes, keeping a reference to globally defined constant variable is safe as it will always be valid.
You can just initialize the member directly:
class Foo
{
int a_, b_;
public:
constexpr Foo(int a, int b) : a_(a), b_(b) {}
};
inline constexpr Foo kFoo{1, 2};
class Bar
{
const Foo& foo_=kFoo;
};
The rest of the world does not have to know it exists and makes the ctor of Bar simpler.
Although it feels slightly redundant, anywhere you can write foo_, you can also write kFoo. Maybe I am misunderstanding your question?
You can add an rvalue constructor to discard rvalue arguments.
class Bar
{
const Foo& foo_;
public:
Bar(const Foo& foo) : foo_(foo) {}
Bar(Foo &&) = delete; // <-- rvalue constructor
const Foo& foo() { return foo_; }
};

Provide default value for constructor initializing reference instance variable

I have a class Foo that has a reference to Bar as an instance variable. Is there a way to have one of the Foo constructors create a Bar instance (so users of the Foo class need not explicitly create a Bar object themselves)?
I'd like to do something like this:
class Foo {
private:
int size;
Bar& bar; // shared by other objects
//several other instance variables
public:
Foo(int s, Bar& b) : size(s), bar(b) {}
// This, of course, doesn't work. I can't think of an
// alternative that doesn't require users of Foo to
// create Bar
Foo(int s) : size(s), bar(Bar(s)) {}
}
(In "real life", Foo and Bar are more complicated. Bar is a friend of Foo that has a private constructor used only by Foo. Each Bar can be shared by several Foos. This isn't a major problem, I'm just curious if it can be done without pointers.)
The simplest solution would be to allocate a Bar if and when you need one. Adding a member std::unique_ptr<Bar> is the easiest way of achieving this. I can't conceive of a system that addresses your problem that will not add some memory overhead to your class. You either have to account for storage for a Bar even when it isn't needed or you have to account for some state to track rather or not your Bar is internally managed. Using a unique_ptr adds the size of a pointer to your class.
#include <memory>
class Foo {
private:
std::unique_ptr<Bar> storage;
Bar& bar;
int size;
public:
Foo(int s, Bar& b) : bar(b), size(s) {}
Foo(int s) : storage(std::make_unique<Bar>(s)), bar(*storage), size(s) {}
};
A more elaborate solution could be to provide a wrapper for Bar that provides a default constructor that takes care of initializing a new instance.
Note that in your example, you do not initialize the member in the same order as they are declared. Members will be initialized in the order they are declared regardless of how you order them in your initialization list.
If every Foo shall have it's own individual Bar-object (not a single shared one), then you could try the following:
class Foo {
private:
Bar& bar; // shared by other objects
int size;
Bar* defaultBar;
//several other instance variables
public:
Foo(int s, Bar& b) : size(s), bar(b), defaultBar(nullptr) {}
Foo(int s) : Foo(s, *(new Bar(14))) { defaultBar=&bar; };
virtual ~Foo() {
if (defaultBar)
delete defaultBar;
}
void setBar(Bar &b) {
if (defaultBar)
delete defaultBar;
defaultBar = nullptr;
bar=b;
}
};
Hope it is what you are looking for.
// This, of course, doesn't work. I can't think of an
// alternative that doesn't require users of Foo to
// create Bar
Foo(int s) : size(s), bar(Bar(14)) {}
You can use a default Bar object, which can be a static member variable of Foo or any other class that can provide such an object.
E.g.
class Foo {
private:
Bar& bar; // shared by other objects
int size;
//several other instance variables
static Bar& getDefaultBar();
public:
Foo(int s, Bar& b) : size(s), bar(b) {}
Foo(int s) : size(s), bar(getDefaultBar()) {}
}
Bar& Foo::getDefaultBar()
{
static Bar b(24);
return b;
}

Call constructor of a member variable without 'new'

I want to call the constructor of a member m_foo of Class A in the constructor of Class A.
Is it nessecary to call it with m_foo = new Foo()? Or can I call it without putting it on the Heap?
I want to pass a pointer to an array of 256 Byte, so that the Foo object fills its member array with the data the pointer points to.
But how would I call a contructor of a member variable that I declare in the headerfile?
A.hpp
class A{
public
A();
private:
Foo m_foo;
};
A.cpp
A::A()
{
//How to call constructor of class Foo here?
}
Foo.hpp
class Foo()
{
Foo(char* p)
{
memcpy(m_Array, p, sizeof(m_Array)/sizeof(m_Array[0]));
}
private:
char m_Array[256];
};
Use the member initialization list for the A constructor :
A::A() : m_foo(...)
{
}
You can get the char* required to build m_foo from :
A constructor :
A::A(char* p) : m_foo(p) {}
Or another function :
A::A() : m_foo(GetBuffer()) {}
If you don't mind passing the pointer to A's constructor, this may be what you want:
class A
{
public:
A(const char* p);
private:
Foo m_foo;
};
A::A(const char* p) : m_foo(p) // <- calls Foo's ctor here
{
}

copy constructor of a vector-derived class

I have the following classes.
class CA {
...
};
class CB: public vector<CA> {
...
};
How shall I implement the copy constructor of CB? i.e.,
CB(CB& cb).
How do I copy the content of the vector of cb in?
Ignoring the issue with publicly inheriting from an std::vector, if you really need a copy constructor for your derived type (for instance, if you are managing dynamically allocated resources), then you can use the constructor initialization list, as in this example, where Foo takes the place of your std::vector in the inheritance hierarchy:
#include <iostream>
struct Foo
{
Foo() {}
Foo(const Foo&) { std::cout << "Copy Foo\n";}
};
struct Bar : public Foo
{
Bar() {}
Bar(const Bar& b) : Foo(b) {}
};
int main()
{
Bar b1;
Bar b2(b1);
}

Assignment operator on only one of two parents

Child has two parents: Foo and Bar. Foo does not allow copying. Bar does. How can Child use Bar's assignment operator to copy into Bar's subset of Child (while leaving Foo's subset intact)?
To be more concrete: in the code below, how can Child refer to just Bar inside replace_bar()? (How would you modify line (X) to make the code compile?)
class Foo
{
public:
Foo () {}
private:
Foo (const Foo & f) {} // forbid copy construction
Foo & operator= (const Foo & foo) {} // forbid assignment
};
class Bar
{
public:
Bar () {}
Bar & operator= (const Bar & bar) {}
};
class Child : public Foo, public Bar
{
public:
Child () {}
void replace_bar (const Bar & bar2)
{
*this = bar2; // line (X)
}
};
int main ()
{
Child child;
Bar newbar;
child.replace_bar (newbar);
}
void replace_bar(const Bar& bar2) {
Bar::operator=(bar2);
}
In other news, you're missing a return *this; in Bar::operator= and if all you want to do is prevent copy of Foo you shouldn't define the copy constructor and assignment operator, only declare them. That way even if you try to use them from within the class you'll get an error (albeit a link error not a compile error).
class Foo {
Foo(const Foo&); // no body
Foo& operator=(const Foo&); // ditto
public:
Foo() { }
};