C++: Immutable method versions - c++

In C++11, what is the best way to provide two versions of a method, one to modify the object itself and one to return a modified copy?
For example, consider a string class which has the "append(string)" method. Sometimes you might want to use append to modify your existing string object, sometimes you might want to keep your string object the same and create a copy.
Of course, I could just implement the first version and manually create a new object everytime I need one but that adds multiple temporary variables and lines of code to my project.
If it is still not clear what I am trying to do:
String s1("xy");
String s2 = s1.appendCopy("z");
s1.appendThis("w");
// s1 == "xyw"
// s2 == "xyz"
In Ruby there is a concept (or rather, a naming convention) which says for such methods, there are two variants: append (creates a new String) and append! (modifies this object)
C++ does not have something like this, so I would be stuck with ugly method names like "appendCopy".
Is there a good way to implement what I am trying to do?
So far, the best idea I had would be to make the modifying versions class members and the copying/immutable versions static methods which take the object to work on as a const argument.

There is actually a guideline, expressed by Herb Sutter in GotW #84:
Prefer non-member non-friend functions.
In your specific case, append (in-place) requires modifying the existing string so is well-suited to be a class-method, while append (copying) does not, so (following the guideline) should not be a class-method.
Thus:
void std::string::append(std::string const&);
inline std::string append(std::string left, std::string const& right) {
left.append(right);
return left;
}
After popular request, here are two overloads that can be used to optimize performance. First the member-version that may reuse its argument's buffer:
void std::string::append(std::string&& other) {
size_t const result_size = this->size() + other.size();
if (this->capacity() < result_size) {
if (other.capacity() >= result_size) {
swap(*this, other);
this->prepend(other);
return;
}
// grow buffer
}
// append
}
And second the free-function that may reuse its right-hand buffer:
inline std::string append(std::string const& left, std::string&& right) {
right.prepend(left);
return right;
}
Note: I am not exactly sure there are not ambiguous overloads manifesting. I believe there should not be...

With the new move semantics you can write:
class A{
public:
// this will get the property
const dataType& PropertyName() const { return m_Property; }
// this wil set the property
dataType& PropertyName() { return m_Propery; }
private:
dataType m_Propery;
};
main()
{
A a;
a.PropertyName() = someValueOfType_dataType; // set
someOtherValueOfType_dataType = a.PropertyName(); // get
}

Related

CPP: Use of deleted function

I am trying to sort a vector that contains custom struct entries using a lambda function in c++ . But I get prompted the following error message
error: use of deleted function ‘dummy_struct& dummy_struct::operator=(const dummy_struct&)
The code looks like the following:
#include <regex>
struct dummy_struct
{
dummy_struct(std::string name, int64_t value_a) :
name(name),
value_a(value_a)
{}
const std::string name;
const int64_t value_a;
int ExtractNumberFromName(std::regex key)
{
int retval;
std::cmatch match;
std::regex_search(this->name.c_str(),match,key);
retval=std::stoi(match[0],nullptr);
return retval;
}
};
void SortByCustomKey(const std::vector<dummy_struct> collection, std::regex key)
{
auto compare = [key](dummy_struct a, dummy_struct b)
{
return a.ExtractNumberFromName(key) > b.ExtractNumberFromName(key)
};
std::sort(std::begin(collection),std::end(collection),compare);
}
int main()
{
std::vector<dummy_struct> test;
test.push_back(dummy_struct("Entry[1]",1));
test.push_back(dummy_struct("Entry[2]",2));
test.push_back(dummy_struct("Entry[3]",3));
SortByCustomKey(test,std::regex("[0-9]+"));
}
What am I missing here?
std::sort sorts vector by swapping it's elements in place.
This requires for your class to implement copy assignment operator (or move assignment), which compiler won't generate for you due to const fields in the class. For your example the only solution seems to remove the const qualifiers from the fields. If you don't want them to be modified just make them private and don't provide (public) setters.
If they absolutely must stay there and you just want to get your values in sorted order you can use a different structure or store pointers in the vector.
Another solution is to write a custom swap implementation for your class that would const_cast away the qualifiers of the fields for the purpose of the assignment, although this is usually a bad code smell.

how to design class that has char* pointer as class member variable?

First i want to introduce my situation :
I have write some classes that has char* pointer as private class member.And also this project has GUI, so when click buttons,some functions may execute more than one time.Those classes are designed single class in project.But some functions of them can execute more than one time.Then I found my project has memory leak.
so i want to ask the following questions:
how to design the set function?
how to design the other functions that use the char* member variable?
how to design the class operator= function?
for example:
class A:
{
public :
setStr(char * s){//need new or just use =?};
A & operator=(const A& other){//also need new?};
manyTimesFunctions(char * other)
{
//need to use chars other to assignment str
//how to carefully use new to avoid memory leak?
//other may be another class's locality none const variable
}
private:
char * str;
}
So ,the project only init class A once,but may use setStr and manyTimesFunctions many times.
May be the answer:
I think i have found what i need to take care of:copy that class,that answers are really useful to me.
Just use std::string. It takes care of memory management for you. The member declaration then looks like
std::string str;
and the setter function looks like
void setStr( char const* s ) { str = s; }
Where you want to use the string and need a char const*, just write str.c_str().
With use of standard library types like std::string, and no manual dynamic allocation, you generally don't need to be concerned about operator=: the compiler-generated copy assignment works nicely.
By the way, it's generally a good idea to decide on some naming convention for member variables. Common ones for C++ include str_, mStr, and my_str. The underscore suffix is perhaps the most common one, but don't use a leading underscore like _str, because although technically allowed it conflicts with the conventions for implementation defined names (e.g. leading underscore is not allowed for identifiers in the global namespace).
I am not 100% sure what you are trying to do. However, since char* is a pointer you may be able to simply pass around the references.
char* operator=(char* s) { str = s; }
Just know that then if you modify value in your function it will modify the place you copied it from
If the char* needs to actually be a clone, so that it does not modify the original value. You first need to obtain the length of the char*.
This can be done with this function
unsigned Length(char* s)
{
unsigned I = 0;
while( *(s+I) != '\0')
I++;
return I;
}
The a new string can be created as follows
str = new char[LENGTH];
At that point you can copy the string over term by term
for(I = 0 ; I < LENGTH; I++)
{
str[I] = s[I];
}
Finally to avoid memory leaks this needs to be deleted in the class destructor
~A()
{
delete [] str;
}
Of course using std::string could save a lot of problems.
This answer will be used to contrast what the other answer(s) given that state to use std::string (and those answers are correct -- use std::string).
Let's assume that you could only use char *, you can't for some reason use std::string, and that you are dealing with NULL terminated strings. This is a synopsis of what your implementation would have to do (and please compare this with simply using std::string):
#include <algorithm>
#include <cstring>
class A
{
public:
// construct empty string
A () : str(new char[1]()) {}
// construct from non-empty
A(const char *s) : str(new char[strlen(s) + 1])
{ strcpy(str, s); }
// copy construct
A(const A& rhs) : str(new char[strlen(rhs.str) + 1])
{ strcpy(str, rhs.str); }
// destruct
~A() { delete [] str; }
// assign
A& operator=(const A& rhs)
{
A temp(rhs);
std::swap(str, temp.str);
return *this;
}
// setter
void setStr(char * s)
{
A temp(s);
*this = temp;
}
// getter
const char* getStr() { return str; }
private:
char * str;
};
Live Example
After adding a couple more constructors and a getter function, this follows the Rule of 3.
You see how much code we needed to add just to make the class safely copyable and assignable? That's why using std::string is much more convenient than using char * when it comes to class members. For std::string a single line needs to be changed, compared to adding the copy / assignment (and move, which I didn't show) functions.
The bottom line is that in C++ if you want strings, use strings (std::string) and try to keep away from using char * (unless you have a very compelling reason to be using char * to represent string data).

Handle object destruction on the stack

I'm currently writing a compiler front end for personal education on the topic and I've run into a problem concerning the way I handle BNF definition in C++ through operator overloading.
Currently my setup is as follows:
Rule.h:
class Rule
{
public:
ChainRule operator>>(Rule& right);
OrRule operator|(Rule& right);
KleeneRule operator*();
OptionalRule Rule::operator+();
virtual bool parse(TokenList::iterator& begin, TokenList::iterator end) = 0;
};
Rule.cpp:
ChainRule Rule::operator>>(Rule& right) {
return ChainRule(this, &right);
}
OrRule Rule::operator|(Rule& right) {
return OrRule(this, &right);
}
KleeneRule Rule::operator*() {
return KleeneRule(this);
}
OptionalRule Rule::operator+() {
return OptionalRule(this);
}
ChainRule, OrRule, KleeneRule, OptionalRule and EmptyRule are defined trivially like so:
class ChainRule : public Rule
{
private:
Rule* next;
Rule* _this;
public:
ChainRule();
ChainRule(Rule* _this, Rule* right);
bool parse(TokenList::iterator& begin, TokenList::iterator end) override;
};
Each subclass of Rule obviously defines a resonable implementation of parse(). Using these classes I can define my grammar as follows:
OrRule assignment_exp = logical_or_exp
| unary_exp >> StringRule("=") >> assignment_exp
;
Now here's the problem: Each overloaded operator returns a new object by value. This means that whenever I use operator>> or operator| from the Rule class, these pointers will be garbage once I return from the call to operator>> or operator| since the stack has been cleaned up and the objects are gone.
Neither can I use pass by value in the constructors for my Rule subclasses since this would not allow me to define recursive grammars.
So I'm left with no option of passing objects by value, and no option of passing objects by pointers. Can anyone point me to a solution that would not force me to define my grammar like so?
StringRule s = StringRule("=");
OrRule assignment_exp;
ChainRule temp1 = s >> assignment_exp;
ChainRule temp2 = unary_exp >> temp1;
assignment_exp = logical_or_exp | temp2;
P.S. I am aware of the various parser generators and Boost.Spirit, but my goal is to write my own parser.
You can allocate the return objects on the heap (via a factory) and return them as references. The factory can keep track of them so you won't leak. As far as syntax is concerned it will work the same as when you return them by value.
You can get around this problem by replacing your Rule* (which have the problem that you cannot overload operators for them) with wrapper objects. I.e. ChainRule would contain RuleRef next instead of Rule * next, etc., and all the operators would be defined for RuleRef. RuleRef would simply contain a Rule*, and be constructable from a Rule*. To make memory handling easier, you could inherit from a smart pointer class.

Avoiding Helper Functions for Doing Comparisons

Say I have a type with a member function:
class Thing {
std::string m_name;
public:
std::string & getName() {
return m_name;
}
};
And say I have a collection of that type:
std::vector<Thing> things;
And I want to keep the things in order by name. To do that, I use std::lower_bound to figure out where to put it:
bool thingLessThan(Thing const& thing, std::string const& name) {
return thing.getName() < name;
}
void addThing(std::string const& name) {
vector<Thing>::iterator position = lower_bound(
things.begin(), things.end(),
name,
thingLessThan);
if (position == things.end() || position->getName() != name) {
position = things.insert(position, Thing());
position->getName() = name;
}
}
Is there a way to do the same thing as the thingLessThan function without actually creating a function, perhaps using std::mem_fun, std::less, etc?
Other than a lambda you can simply define an operator< which adheres to strict weak ordering to allow a container of your object to be comparable by STL algorithms with the default predicate std::less
class whatever
{
public:
bool operator<(const whatever& rhs) const { return x < rhs.x; }
private:
int x;
};
std::vector<whatever> v;
std::sort(v.begin(), v.end());
Sure. You can use a lambda expression (assuming your compiler supports it):
vector<Thing>::iterator position = lower_bound(
things.begin(), things.end(),
name,
[](Thing const& thing, std::string const& name) { return thing.getName() < name; });
Of course, an alternative option is just to define operator< for the class, then it will be used by default, if you don't specify another comparer function for std::lower_bound.
Depending on what your purpose is? If you just like the syntactic niceness of not declaring something to be used in one place, use lambda expressions to create an anonymous function.
You can overload operator<() and use std::less<T> if you don't want to write predicates contantly. Also you can use lambda-expressions, which would be much nicer, because operator<() is logically connected only with things, that can be put in some order in obvious ways, like numbers or strings.
If you use a std::map, the strings will be placed in alphabetical order automatically. If you want to modify the ordering further, create your own key comparison function. I think this would be the simplest option.
To use a std::list, you can write your own comparison code inside of the addThing() function that goes through the list looking at each string and inserts the new one at the appropriate place.

Find array element by member value - what are "for" loop/std::map/Compare/for_each alternatives?

Example routine:
const Armature* SceneFile::findArmature(const Str& name){
for (int i = 0; i < (int)armatures.size(); i++)
if (name == armatures[i].name)
return &armatures[i];
return 0;
}
Routine's purpose is (obviously) to find a value within an array of elements, based on element's member variable, where comparing member variable with external "key" is search criteria.
One way to do it is to iterate through array in loop. Another is to use some kind of "map" class (std::map, some kind of vector sorted values + binarySearch, etc, etc). It is also possible to make a class for std::find or for std::for_each and use it to "wrap" the iteration loop.
What are other ways to do that?
I'm looking for alternative ways/techniques to extract the required element.
Ideally - I'm looking for a language construct, or a template "combo", or a programming pattern I don't know of that would collapse entire loop or entire function into one statement. Preferably using standard C++/STL features (no C++0x, until it becomes a new standard) AND without having to write additional helper classes (i.e. if helper classes exist, they should be generated from existing templates).
I.e. something like std::find where comparison is based on class member variable, and a variable is extracted using standard template function, or if variable (the one compared against "key"("name")) in example can be selected as parameter.
The purpose of the question is to discover/find language feature/programming technique I don't know yet. I suspect that there may be an applicable construct/tempalte/function/technique similar to for_each, and knowing this technique may be useful. Which is the main reason for asking.
Ideas?
If you have access to Boost or another tr1 implementation, you can use bind to do this:
const Armature * SceneFile::findArmature(const char * name) {
find_if(armatures.begin(), armatures.end(),
bind(_stricmp, name, bind(&string::c_str, bind(&Armature::name, _1))) == 0);
}
Caveat: I suspect many would admit that this is shorter, but claim it fails on the more elegant/simpler criteria.
Sure looks like a case for std::find_if -- as the predicate, you could use e.g. a suitable bind1st. I'm reluctant to say more as this smacks of homework a lot...;-).
Why 5 lines? Clean doesn't have a number attached to it. In fact, clean code might take more lines in the utility classes, which can then be reused over and over. Don't restrict yourself unnecessarily.
class by_name
{
public:
by_name(const std::string& pName) :
mName(pName)
{}
template <typename T>
bool operator()(const T& pX)
{
return pX.name == pName;
}
private:
std::string mName;
};
Then:
const Armature* SceneFile::findArmature(const char* name)
{
// whatever the iterator type name is
auto iter = std::find_if(armatures.begin(), armatures.end(), by_name(name));
return iter == armatures.end() ? 0 : &(*iter);
}
Within restriction:
class by_name { public: by_name(const std::string& pName) : mName(pName) {} template <typename T> bool operator()(const T& pX) { return pX.name == pName; } private: std::string mName; };
Then:
const Armature* SceneFile::findArmature(const char* name)
{
// whatever the iterator type name is
auto iter = std::find_if(armatures.begin(), armatures.end(), by_name(name));
return iter == armatures.end() ? 0 : &(*iter);
}
:)
C++0x has ranged-based for-loops, which I think would make the most elegant solution:
const Armature* SceneFile::findArmature(const std::string& pName) const
{
for (auto a : armatures)
{
if (a.name = pName) return &a;
}
return 0;
}
You would probably need to use STL map. It gives you possibility to get the element using keys. Your key would be the name of armature.
http://www.cplusplus.com/reference/stl/map/
EDIT: :D
one liner B-)
const Armature* SceneFile::findArmature(const Str& name){for (int i = 0; i < (int)armatures.size(); i++) if(name == armatures[i].name) return &armatures[i]; return 0;}
Holy shiz, you're using _stricmp? FAIL. Also, you didn't actually tell us the type of the vectors or any of the variables involved, so this is just guesswork.
const Armature* SceneFile::findArmature(const std::string& lols) {
for(auto it = armatures.begin(); it != armatures.end(); it++) {
if (boost::iequals(lols, (*it).name))
return &(*it);
return NULL;
}
Ultimately, if you need this, you should put the armatures or pointers to them in a std::map. A vector is the wrong container if you're searching into it, they're best for when the collection is what's important rather than any finding behaviour.
Edited to use a std::string reference.