I am puzzled because I cannot figure where my bug/problem is.
I have a class Instruction, which uses two custom operators, one assignment and one comparison operator.
Previously I only used the comparison operator in order to use std::sort to sort Instructions based on one of their members, an std::string name.
However, since I started re-factoring the entire project, I changed some members to constant. This lead me to having to use an initialization list for those constants.
This in turn, lead me to have to create an assignment operator, because those instructions are being copied when pushed back in vectors.
This is where everything goes wrong.
I include my Class declaration and Constructor and Operators.
instruction.hpp
class Instruction
{
private:
unsigned int param_size;
const float max_angle, min_angle;
bool micro_mutated;
protected:
const std::string body_part;
std::vector<Parameter <float> > parameters;
public:
Instruction(std::string name, float max, float min);
Instruction operator=(const Instruction& I);
bool operator<(const Instruction& I) const;
//there are a few more functions but are completely irrelevant
}
instruction.cpp:
Instruction::Instruction(std::string name,float max, float min) :
body_part (name), max_angle(max), min_angle(min)
{}
Instruction Instruction::operator=(const Instruction& I)
{
(*this) = I;
return (*this);
}
bool Instruction::operator<(const Instruction& I) const
{
return body_part < I.body_part;
}
The only reason why I created an assignment operator (which to be honest I've never done before) was because when I was trying to push_back Instructions, compiler complained about not being able to instantiate "from here" Instructions and I thought it had to do with the constant members. Without the members being constant, everything worked fine, even the sorting.
Now the weird part. If I remove the std::sort, the above code works, but not all the time. Some times it crashed after a while, some times it won't crash. But the moment I include the sorting, it crashes straight away.
Can someone please help ?
Don't forget the rule of threes: if you have one of a copy construct, copy assignment operator, and destructor, then you should have all of them.
However, your copy assignment operator is effectively an infinite loop; it calls itself. Operator= will be used whenever you have anything of the form: Instruction &=Instruction&. Which is exactly what (*this) = I is.
My question is this: why are those things constant? Having members be constant effectively means that you cannot copy the object (unless you use a const-cast) with copy assignment. You can copy construct them, but that's about it.
Is there some reason for those members to be constant? And if so, then you shouldn't be copying these objects by assignment. The two are mutually exclusive.
If you need a member to be effectively constant, unchangable by outside activity (but not language-const which prevents copying), then this should be done with proper accessor methods. Provide users of the class with ways to get these values, but not ways to set them.
Related
struct Task{
int value,time,deadline;
bool operator < (const Task& t1)const{
return d<t1.deadline;
}
}task[1000];
I've read this block of code of struct initialization.
the first line, initialize variables, is easy to grasp.
What about the second line? the bool operator thing. Seems like some kind of sorting rules. I have never seen any code like this in cpp before, could someone help me to understand it?
What you observe is called operator overloading. In this case the operator< is overloaded for class Task.
This is done in order to be able to write something like this.
Task t1{1,2,3};
Task t2{2,3,4};
if(t1 < t2) //note, the operator< is called
{
//do your thing
}
To add to the answer, I would like to point out that the variables are not initialized (in traditional sense). It is so called default initialization or, rather, a lack of initialization as the variables will be of whatever value that happened to be in the memory at that time.
To zero-initialize the array, you'll need to use the following syntax (that resembles calling a default constructor of an array)
struct Task{
int value, time, deadline;
bool operator < (const Task& t1) const {
return deadline < t1.deadline;
}
} task[1000]{};
...Well, it's simple in your case, since you don't have any user-declared constructors, but in other cases it may become tricky. Read this if you're interested value-initialization.
(And {} is a new syntax for constructing objects introduced in C++11. The prior syntax () has several issues: it does not check that arguments are narrowed, and it suffers from the most vexing parse problem, when Foo aVariable(std::string("bar")); is parsed as function declaration (see).)
I have started to develop with C++ and I have a doubt about copy constructor and assignment operator.
I have this class:
class MyTime
{
private:
unsigned char _hour;
unsigned char _minute;
float _second;
signed char _timeZone;
unsigned char _daylightSavings;
double _decimalHour;
public:
MyTime(unsigned char hour, unsigned char minute, float second, signed char timeZone, unsigned char daylightSavings);
MyTime(const MyTime& copySource);
MyTime& operator=(const MyTime& source);
~MyTime();
unsigned char getHour();
unsigned char getMinute();
float getSeconds();
signed char getTimeZone();
unsigned char getDayLightSavings();
double getDecimalHour();
};
And copy constructor and assignment operator implementation:
MyTime::MyTime(const MyTime& copySource)
{
this->_hour = copySource._hour;
this->_minute = copySource._minute;
this->_second = copySource._second;
this->_timeZone = copySource._timeZone;
this->_daylightSavings = copySource._daylightSavings;
}
MyTime& MyTime::operator=(const MyTime& source)
{
this->_hour = source._hour;
this->_minute = source._minute;
this->_second = source._second;
this->_timeZone = source._timeZone;
this->_daylightSavings = source._daylightSavings;
return *this;
}
Are these implementations required?
I need to make sure that when I assign an instance of MyTime it will create a new instance with its values.
Your copy constructor and assignment operators are just copying the values from copySource and source respectively into your instance.
You're not creating a new instance, just overwriting your instance's values with those of copySource and source.
As it stands, your class doesn't even require writing copy constructor and assignment operator since the compiler will implicitly generate them for you.
This is a feature of the C++ language, I recommend reading more about this here: Copy constructors in C++ (ndMarco: I understand this might not be the easiest source to learn from, but it is one of the most complete and accurately written available).
Copying each member variable from an instance to another is not a deep-copy problem and thus no action is required on your side.
As a follow-up for your studies take a look at the rule of three/five/zero. Start with the rule of three (understand why your class doesn't need any of them and what would happen if it needed one of them) and then move on to understanding C++11 concepts.
One last secondary thing: using a verbose this->member_variable isn't needed in C++ unless you need to make it clear you're referring to a member variable instead of a local one e.g.
class MyClass {
public:
int value = 33;
void function() {
int value = 42; // Now there's confusion
std::cout << value; // 42
}
};
so in your case this-> is not required. Anyway as a style preference you might still use it to make it clear you're referring to a member variable of that class. Just be aware of this small caveat. This is intended as an addition to the fact that you should not name your local variables and class members in the same way (that's a terrible practice).
There are still many things that could be added or built over these concepts but they would steer this post off-topic. Just make your mind on these preliminary concepts and you might call it a day.
No. Your class as it stands does not require copy constructor, assignment operator or destructor. The compiler-generated ones will do exactly what you require.
Also, from a style POV, you don't need all the "this->" stuff to access class members, unless you're choosing bad names for local variables, or are doing complex template-related stuff.
It's fine not to do it, as your compiler should generate them for you. However, this is not that case in all classes. A compiler generated copy constructor/assignment operator will basically just use the = operator for everything, which is not a good case if you are using pointers and dynamic memory:
Take a string class. You have a char* which you reallocate with internal functions inside the string class and assign using functions like copy, e.t.c.
However, if a copy construct/assignment operator is omitted for a class like a string, the compiler should automatically create one, which unlike what you want, will simply point your pointers to the pointer of the class to be copied from, which will cause large errors, as once that class is modified, your string will also be modified as they both point to the same memory. As a result, for classes that you do not want the compiler to use a simple operator= on all the members with, you should define the copy constructor/operator=... otherwise there is no need as long as you have a good compiler
Note: you do not need this-> to access the members as you are not inheriting them from a templated class.
No, your code is equivalent to the default copy-constructor and assignment operator. A compiler will generate these as needed. As a rule of thumb, you need to define your own versions if you use dynamic memory or some objects without copy semantics.
As a simple example, if you write new in your constructor, you will have to write a matching delete in your destructor, and then by the rule of three you will have to do something with a copy-constructor and an assignment operator. If you avoid managing memory manually, you don't have to worry about these.
Programming in C++, I often want to give the user of a class read-only access to an attribute, and the class itself read-write access. I hate XxxGet() methods, so I often use a public const & to a private attribute, like this:
class counter {
private:
int _count;
public:
const int & count;
counter : _count( 0 ), count( _count ){}
void inc( void ){ _counter++; }
};
Is there a common name for this trick?
My personal name for that trick would be bad idea.
I would avoid the approach that you are following, as it incurs extra unneeded cost. If you add accessors they can be inlined as needed, with the only penalty of having to type an extra pair of parentheses:
class counter {
int _count;
public:
counter() : _count() {}
int count() const { return _count; }
void inc() { ++_count; }
};
The main difference is that in your solution you are incrementing the size of the object by one reference (for most implementations this means pointer), and then each access requires an extra indirection. On the other hand, with the accessor, the actual variable is used, the function will be optimized away (inlined, and resolved to a single read to the variable).
As of a proper name for that type of construct, well, I have never seen your particular construct in C++, but if you consider other languages, that is the basic concept of a property in C#, where you can make the getter public and the setter private.
EDIT: I guess that bad idea can be misinterpreted as just a personal opinion (which it is), but consider the side effects of that design:
Because of the reference in the object, you inhibit the implicit definition of the assignment operator. Much worse, the copy constructor will compile but not work as expected:
// consider the implementation with the const reference
counter c1;
counter c2( c1 ); // compiles, so it must work
c2.inc();
std::cout << c2.count; // outputs 0
// c2 = c1; // error: well, at least this does not compile!
The problem is that the compiler generated copy constructor will make the count reference in c2 refer to the same int that the count reference in c1 refers to, which might lead to hard-to-find subtle issues in your code that are actually quite hard to debug.
Edit
Just now I thought of a name that could be considered the same pattern. Though not typically used for member variables.
There could actually be a name for this, as has been made popular by the Boost Tuple library as well as the TR1/C++11 implementations:
Tieing
Typical example:
tuple<int> tie(ref(some_var));
// or shorter:
auto tied = tie(var1, var2, var3);
Assignment complications
The closest name for this (anti?) pattern I could _immediately think of before, is: pointer or reference aliasing. It is not a very good idea for many reasons, some of which have been mentioned
class layout + size
copy/assignment semantics
compiler optimizations: the compiler will shun from making assumptions about the value of (register-allocated) variables when it knows references could point to the same memory location.
In addition to the points David makes, the compiler will be unable to generate default
semantically valid copy constructor
assignment operator
move assignment operator
for your class now that contains references. Note also that your class can't possibly be POD anymore
A number of others have already condemned this idea, and I (mostly) tend to agree with them. Although quite a few people probably dislike it (at least) as much, if I was going to support something on this order, I'd do something like this:
class counter {
int count_;
public:
counter(int init=0) : count_(init) {}
operator int() const { return count_; }
void inc() { ++count_; }
};
The one problem with this is one that's shared with implicit conversions in general: that the implicit conversion can happen even when you don't want it to. OTOH, the fact that it's a user-supplied conversion actually eliminates many of the problems -- only one implicit conversion will happen automatically in any given situation, so (for example) the fact that you've supplied a conversion to int will not mean that a counter with a value of 0 can be implicitly converted from a counter to an int to a (null) pointer to T, because that would involve two implicit conversions.
There are times this can cause a problem anyway, in which case (as of C++11) you can make the conversion operator explicit, so it'll only happen when/if the user does an explicit conversion like:
counter t;
int x = t; // allowed by code above, but not with `explicit` conversion operator.
int y = static_cast<int>(t); // allowed with `explicit` conversion operator.
ostream& operator<<(ostream& out, const hashmap& h)
{
const char *getSymbol = NULL;
h.hashTable->displayHeaders(out);
for ( int hashIndex = 0; hashIndex < maxSize; hashIndex++ )
{
getSymbol = h.hashTable[hashIndex].getSymbol();
if ( getSymbol )
{
out << h.hashTable[hashIndex];
}
}
return out;
}
If I read the code right as the formatting is somewhat off, the problem is most likely that your stock copy constructor does a shallow copy whereas the assignment operator for the same class makes a deep copy. From reading the rest of the code, I assume you meant to make a deep copy instead of just duplicating the m_name and m_symbol pointers.
I'd also strongly suggest that you use std::string instead of raw char pointers - doing that in the first place would have avoided the issues I describe above. It would've also allowed you to use the compiler generate copy constructor, assignment operator and destructor. Less code is good.
Something went wrong with the formatting when you posted your code, so I had to move it to an external editor to read.
The problem is not a memory leak - that would be memory that you failed to reclaim. This is quite the opposite issue. Here, you are trying to reclaim memory that was already freed.
I would bet anything that the failing delete call in the destructor is occuring on an object that was either copied or populated using either the copy constructor or the second overloaded assignment operator. You are performing a shallow copy in those places, resulting in two stock objects referencing exactly the same memory for their mname and msymbol members. Whichever one of the two (or more if you copied many times) is destroyed first will have no problems. Whichever one is destroyed second will fail.
I also make the following observation: your constructor carefully checks symbol and name to see if they actually reference any data. Only then do you proceed to use their values. If they are null, then you assign a value of null to the corresponding members. The first overloaded assignment operator, on the other hand, is copying an instance of stock that for all you know could have null mname or msymbol members. You should treat those values with the same care you did in the constructor and test them before using.
The problem is here:
stock& stock::operator=(stock const * const s)
Look at the logic of this operator and the other assignment operator you declared: you copy m_symbol and m_name differently!
You would be better off defining the assignment operator only once:
stock& stock::operator=(stock const * const s)
{
return this->operator=(*s);
}
Or the other way around if you prefer, but remember that the implementation of this one is off.
Consider a class of which copies need to be made. The vast majority of the data elements in the copy must strictly reflect the original, however there are select few elements whose state is not to be preserved and need to be reinitialized.
Is it bad form to call a default assignment operator from the copy constructor?
The default assignment operator will behave well with Plain Old Data( int,double,char,short) as well user defined classes per their assignment operators. Pointers would need to be treated separately.
One drawback is that this method renders the assignment operator crippled since the extra reinitialization is not performed. It is also not possible to disable the use of the assignment operator thus opening up the option of the user to create a broken class by using the incomplete default assignment operator A obj1,obj2; obj2=obj1; /* Could result is an incorrectly initialized obj2 */ .
It would be good to relax the requirement that to a(orig.a),b(orig.b)... in addition to a(0),b(0) ... must be written. Needing to write all of the initialization twice creates two places for errors and if new variables (say double x,y,z) were to be added to the class, initialization code would need to correctly added in at least 2 places instead of 1.
Is there a better way?
Is there be a better way in C++0x?
class A {
public:
A(): a(0),b(0),c(0),d(0)
A(const A & orig){
*this = orig; /* <----- is this "bad"? */
c = int();
}
public:
int a,b,c,d;
};
A X;
X.a = 123;
X.b = 456;
X.c = 789;
X.d = 987;
A Y(X);
printf("X: %d %d %d %d\n",X.a,X.b,X.c,X.d);
printf("Y: %d %d %d %d\n",Y.a,Y.b,Y.c,Y.d);
Output:
X: 123 456 789 987
Y: 123 456 0 987
Alternative Copy Constructor:
A(const A & orig):a(orig.a),b(orig.b),c(0),d(orig.d){} /* <-- is this "better"? */
As brone points out, you're better off implementing assignment in terms of copy construction. I prefer an alternative idiom to his:
T& T::operator=(T t) {
swap(*this, t);
return *this;
}
It's a bit shorter, and can take advantage of some esoteric language features to improve performance. Like any good piece of C++ code, it also has some subtleties to watch for.
First, the t parameter is intentionally passed by value, so that the copy constructor will be called (most of the time) and we can modify is to our heart's content without affecting the original value. Using const T& would fail to compile, and T& would trigger some surprising behaviour by modifying the assigned-from value.
This technique also requires swap to be specialized for the type in a way that doesn't use the type's assignment operator (as std::swap does), or it will cause an infinite recursion. Be careful of any stray using std::swap or using namespace std, as they will pull std::swap into scope and cause problems if you didn't specialize swap for T. Overload resolution and ADL will ensure the correct version of swap is used if you have defined it.
There are a couple of ways to define swap for a type. The first method uses a swap member function to do the actual work and has a swap specialization that delegates to it, like so:
class T {
public:
// ....
void swap(T&) { ... }
};
void swap(T& a, T& b) { a.swap(b); }
This is pretty common in the standard library; std::vector, for example, has swapping implemented this way. If you have a swap member function you can just call it directly from the assignment operator and avoid any issues with function lookup.
Another way is to declare swap as a friend function and have it do all of the work:
class T {
// ....
friend void swap(T& a, T& b);
};
void swap(T& a, T& b) { ... }
I prefer the second one, as swap() usually isn't an integral part of the class' interface; it seems more appropriate as a free function. It's a matter of taste, however.
Having an optimized swap for a type is a common method of achieving some of the benefits of rvalue references in C++0x, so it's a good idea in general if the class can take advantage of it and you really need the performance.
With your version of the copy constructor the members are first default-constructed and then assigned.
With integral types this doesn't matter, but if you had non-trivial members like std::strings this is unneccessary overhead.
Thus, yes, in general your alternative copy constructor is better, but if you only have integral types as members it doesn't really matter.
Essentially, what you are saying is that you have some members of your class which don't contribute to the identity of the class. As it currently stands you have this expressed by using the assignment operator to copy class members and then resetting those members which shouldn't be copied. This leaves you with an assignment operator that is inconsistent with the copy constructor.
Much better would be to use the copy and swap idiom, and express which members shouldn't be copied in the copy constructor. You still have one place where the "don't copy this member" behaviour is expressed, but now your assignment operator and copy constructor are consistent.
class A
{
public:
A() : a(), b(), c(), d() {}
A(const A& other)
: a(other.a)
, b(other.b)
, c() // c isn't copied!
, d(other.d)
A& operator=(const A& other)
{
A tmp(other); // doesn't copy other.c
swap(tmp);
return *this;
}
void Swap(A& other)
{
using std::swap;
swap(a, other.a);
swap(b, other.b);
swap(c, other.c); // see note
swap(d, other.d);
}
private:
// ...
};
Note: in the swap member function, I have swapped the c member. For the purposes of use in the assignment operator this preserves the behaviour to match that of the copy constructor: it re-initializes the c member. If you leave the swap function public, or provide access to it through a swap free function you should make sure that this behaviour is suitable for other uses of swap.
Personally I think the broken assignment operator is killer. I always say that people should read the documentation and not do anything it tells them not to, but even so it's just too easy to write an assignment without thinking about it, or use a template which requires the type to be assignable. There's a reason for the noncopyable idiom: if operator= isn't going to work, it's just too dangerous to leave it accessible.
If I remember rightly, C++0x will let you do this:
private:
A &operator=(const A &) = default;
Then at least it's only the class itself which can use the broken default assignment operator, and you'd hope that in this restricted context it's easier to be careful.
I would call it bad form, not because you double-assign all your objects, but because in my experience it's often bad form to rely on the default copy constructor / assignment operator for a specific set of functionality. Since these are not in the source anywhere, it's hard to tell that the behavior you want depends on their behavior. For instance, what if someone in a year wants to add a vector of strings to your class? You no longer have the plain old datatypes, and it would be very hard for a maintainer to know that they were breaking things.
I think that, nice as DRY is, creating subtle un-specified requirements is much worse from a maintenance point of view. Even repeating yourself, as bad as that is, is less evil.
I think the better way is not to implement a copy constructor if the behaviour is trivial (in your case it appears to be broken: at least assignment and copying should have similar semantics but your code suggests this won't be so - but then I suppose it is a contrived example). Code that is generated for you cannot be wrong.
If you need to implement those methods, most likely the class could do with a fast swap method and thus be able to reuse the copy constructor to implement the assignment operator.
If you for some reason need to provide a default shallow copy constructor, then C++0X has
X(const X&) = default;
But I don't think there is an idiom for weird semantics. In this case using assignment instead of initialization is cheap (since leaving ints uninitialized doesn't cost anything), so you might just as well do it like this.