I am in the process of learning C++ in order to understand some open source code I have been given.
I came across a line as follows:
cmd << '\n'
I assumed that "cmd" must be some kind of special receptor for a stream, perhaps a string - but on further investigation I found that "cmd" was an entire class with assorted data and functions. This has completely confused me. Why doesn't the code look like this:
cmd.stringpart << '\n'
Can someone tell me what's going on, or suggest an article for me to take a look at.
CORRECTION: cmd is an instance of a class rather than the class itself.
In C++, you can overload operators. In this case it seems to be used to make some Cmd class behave like a stream.
See operators as functions: For instance, 3 + 4 calls a binary function taking two numbers and returning the sum of them.
Here, the author has created such a function to define the << operator, so that it can work with a cmd class instance as the left parameter, and a string as the right parameter. This is called "operator overloading". Look for operator<< occurrences in your code.
This can also be a member function of the cmd class, taking one parameter (still named operator<<).
I'd first check to see if the class of which cmd is an instance overrides the << operator - that would show you what is going on in this code.
check for operator overloading in this class - you should seek for function with '<<' in it's name.
It sounds like the ostream operator (<<) has been overloaded. Look for a method called "operator<<" in the class definition. C++ allows programers to "overload" or redefine the way operators (including +,-,*,/,++,--, etc) work with their classes. Consult any C++ text for a discussion of this.
In many languages including C++
you are allowed to do what it is called "operator overload"
In your code if you have an operation for example that you perform repeatedly, generally for the sake of cleaner and handier code, you can pick an existing operator (such as --, +=, ==, <<, >>) and re-define it locally aka overriding, then use it as you please.
There are also some cases that you override the operator to create the functionality you want in a library. For example:
- You created a class mainly to store blocks of information. Then, you use container classes (from various libraries) to store instances of your class.
Foo {
int a;
int b;
std::string c;
}
So usually every container class will have methods to juggle around, delete, add, compare (...) instances stored. Let's say you want to compare an instance of Foo foo with woo = FooContainer[0] stored in your container with "==" in, some libraries will require you to re-define so override the "== " operator anyways, where some will assume. For instance, they will return true only if( foo.a == woo.a && foo.b == woo.b && foo.c == woo.c ) is true.
Well, maybe two instances is the same for your use only if their 'c' is the same, then you can just override "==". You typically would do that in Foo, right under the constructor. It'd look similar to this:
bool operator==(const Foo &foo) const {return c == foo.c;}
Bottomline:
If there is an operation you couldn't make sense, you might want to look at technical guide if exist. If not, go to header files, override classes etc to explore overwritten operators before go deep in the code.
You also wanna get familiar with them yourself, because (a) you might HAVE to use in some cases, (b) it might give you functionality you want super easily, (c) it can make your code clean and simple.
Hope it helps..
Related
So I am trying to do something, but I am not sure it can/should be done this way in c++.
I have a file of objects I want to read in. Each object is of one of 3 types of classes which are part of a hierarchy
In the file I have a discriminator to tell me which is which.
Lets say the classes are:
Checking, Savings and are subclasses of Account.
Can i build code such that:
Account a;
istream >> a;
Will let me polmorphically set the resulting data in a to the appropriate type ?
( i realize the code would have to be there to do it)
Hope that makes sense. Or, do i just need a "deserialize" method or something that i don't use operator overloading for?
I can't use any existing non STL libraries out there, as this is for a classroom example.
Thanks!
Edit: I think my question may have been unclear:
friend istream& operator>>(istream& is, Transactions& transactions)
{
is my function, and i want to have transaction set to a subclass of Transaction....
I'm thinking this isn't possible without some of the new newer features
some have mentioned?
If you want polymorphism you need pointers or references. Objects are always the type you declare them as. Nothing more, nothing less.
So you need a separate factory function that can decide which type to create at runtime. For example, it could look something like this:
std::unique_ptr<Account> read_account(std::istream& is)
{
std::string type = read_type(is);
if (type == "checking") {
auto acct = std::make_unique<Checking>();
is >> *acct;
return acct;
} else {
auto acct = std::make_unique<Savings>();
is >> *acct;
return acct;
}
return {}; // or throw
}
C++ does not work this way, on a fundamental level. Quoting from your question, if you have a declaration:
Account a;
Then that's what a is. In C++, the types of all objects must be known at compile time. This is fundamental to C++, there are no exceptions or workarounds. The type of a cannot be changed at runtime, based on some arbitrary criteria.
Will let me polmorphically set the resulting data in a to the
appropriate type ?
Nope. a is an Account. This is immutable, and cannot be changed based on runtime conditions.
Or, do i just need a "deserialize" method
That would be a very common approach, and was pretty much the rule of the land before C++17.
In C++17 you could declare an
std::variant<std::monostate, Checking, Savings> a;
And then define an implement a >> for this, which will replace the default-constructed a monostate with an instance of one or the other class.
Note that the type of the object a is still fixed, and no rules are broken: a is a variant type. It has a specific type that's defined at compile-time.
This quesiton is composed of a couple parts, the first has to do with the -> operator in a class. Does it take some sort of input (according to the C++ standard)? For example
some_return_type? operator->( long address ) {
cast the address to some sort of pointer and do something with it...
return something?...possibly... maybe not?;
}
So in reality A::SomeMethod() would refer to an address for a function in memory passed to ->. Or
A::someStaticOrNonStaticDataMember would refer to an address for a field?
If so (given that we do not have access to the actual type of the class), or something like this exists, what is it, and can we reconstruct part of a pointer, or align a pointer, (or write a class with an algorithm to do this), for a class based on some information about that class, so that it had an operable -> operator, so one could write:
somePointer->A::SomeMethod();
and have it call A::SomeMethod()? And maybe make context for the memory used in the class?
From the comments it seems you want to control how Compiler handles and generates -> tokens. This is for your bad luck not possible, because Compiler doesn't expose such information, nor is it required by Standard to do so
It is like you are trying to have "dynamic" (the C# type) but in C++, unluckily this is not possible. What could be similiar is wrapping some sort of "Closure collection" addressed by strings (a sort of scripting language) but that would be really heavy and not very nice.
Actually doing what you want with the syntax you showed is not possible.
If the type of an object is not known, then you have that object hided behind a "void *". That means basically that the only way you can use that object is by casting it back to its original type.
Suppose you have a DLL that expose 2 functions (with header files)
// creates an object of given type or null_ptr if no object match
void* getObject(std::string obj_type);
// call a method on that object
void callMethod(void* obj, std::string method_name, void* args, void* returnval);
Actually that solution (even if ugly) allows to call methods on objects that you don't know (it could be a lot better than that.)
But that force you to use void* and strings. That's because how C++ resolve method names (in reality also in C# the "dynamic" type generates behind the scenes reflection code that use strings with method names and is particulary slow)
So something similiar can be achieved with
float fuelLiters = 3.0f;
void * myObj = createObject("SomeCar");
callMethod(myObj,"loadFuel", &fuelLiters, null_ptr);
you probably can make the syntax a little better with templates or some macro, but you'll never be able to do something like
myObj->A::loadFuel(fuelLiters);
What you can do is having the externally loaded class, use the same interfaces of your application, says:
class ICar{
public:
void loadFuel(float liters)=0;
};
In that case you can use a function that cast the opaque object handle to ICar. This is what I already doing in a library I wrote 2 years ago:
So you just need the DLL expose a method for casting the class (downcast)
//if given object is implementing a ICar, the correct pointer is returned, else
// this function will return nullptr (or throw exception if you like more)
void * downcast( typeof(ICar), myObj);
You'll need simply
ICar *myCar = static_cast<ICar>(downcast( typeof(ICar), myObj));
myCar->loadFuel(3.0f);
However note that both the DLL and your application should "know" about what "ICar" is, so they must include the "ICar" header.
doing that is definitely possible, I did it already in 2 different ways, so If you need more details about implementation I'll be happy to show a possible way (given I understood correctly your question).
The arrow operator (->) is a dereference operator that is used exclusively with pointers to objects that have members.
foo->bar() is the same as (*foo).bar()
If you want to overload -> you should also overload *
I need to draw my object on an out stream, which is usually cout.
But I also want the user to be able to input any stream that has << operator (such as QTextStream), so it doesn't have to be cout every time.
What's the easiest way to define such parameter?
So this is what I'd like to have, something compilable tho:
virtual void draw(GeneralOutStream out = std::cout)
{
out << m_name << std::endl;
}
I know I could use templates, (which is what I'm doing atm.) but I was hoping there would be a solution that doesn't require templates.
However, the template solution works fine, so basically I'm just curious.
I can think of Four approaches.
First, take std::ostream as your GeneralOutStream, and assume everyone inherits from it. Maybe write some stuff that wraps a QTextStream up in a way that makes it a std::ostream.
Second, write a template method that takes GeneralOutStream&& out and operates on it. This requires exposing your implementation in your header. I'd recommend this one. Quite strongly, but it does mean that virtual ends up being pretty useless.
Third, write a type erasure GeneralOutStream that exposes the parts of the general out stream you want to interact with within your class with a template constructor that stores the passed in generic type in a pImpl with virtual methods, then use that type within the implementation of your object. This has runtime overhead and is quite tricky to write, and resembles the pattern of std::function -- except GeneralOutStream has to handle being able to write an entire myriad of types!
If I was to write #3, GeneralOutStream would be a template that takes a sequence of types the GeneralOutStream is supposed to handle, then does some metaprogramming to expose exactly those overloads to <<. This gets really tricky, because you need to replicate overload resolution manually.
Forth, create an enumeration of "GeneralOutStream" types that you want to support. Use double-dispatch techniques to ferry references to instances of those types through a virtual method call, unbundling them at the other side and calling your implentation template methods, requiring that the implementing class handle the entire enumeration. This one is slightly less tricky to implement than #3, limits what types you can pass to the draw method, but allows full access to the type in the implementation class.
You want a solution any stream (derived from std::ostream) or for any object that has << operator?
In the first case, you can pass a reference to the stream object:
virtual void draw(std::ostream& out = cout) {
out << m_name << std::endl;
}
Passing a copy won't compile.
In the second case, the main problem is the interface, since it looks you want to define that function as virtual member. If is not the case and you still want a solution for any object (not necessary standard ostream, but any with operator << defined), you'll have to use templates.
My situation is a follows: There is some class MyList that will probably get a specific implemenation later on. For now, behavior like std::vector is fine.
However, I really need an easy way to call some kind of asString() / toString() method on it, because I'll need it in test assertions, debug output and so on. The only options I see are:
Public inheritence. I'll never delete such a list through a base-pointer, since there should never be any base pointers. If I do, there will be no pointer members, anyway. However, rule of thumb still states: Don't inherit from stl containers.
Some kind of "global" (actually in a namespace, of course) method that takes an instance of MyList as argument and does the asString() magic for me. In that case, MyList could be a simple typedef for std::vector.
I like neither of those options too much. Is there something else I failed to think of? Or if not - which way should I prefer?
what is wrong about the second approach? that is by far the easiest and also pretty elegant.-
Imagine the alternative of wrapping the vector. that would cause you alot of extra work and glue code that is error prone! I'd go with the function approach for sure!
edit: btw, i almost exclusively use free functions(sometimes static members) for conversions. Imagine you have a load of types that somehow need to be convertible to string. Having the toString() functions as free functions and not as members does not give you the headache you are heaving right now since you can basically simply overload the function as much as you want and don't have to touch any existing classes (or maybe classes that you don't even have source access to).
Then you can have a function like:
template<class T>
void printDebugInfo(const T & _obj)
{
std::cout<<toString(_obj)<<std::endl;
}
and you wont have the constraints you are experiencing.
Actually, free functions upon class types are a standard technique and are considered as part of the interface of a type. Read this GotW by Herb Sutter, one of people that have a voice in C++ standardization.
In general, prefer free functions over member functions. This increases encapsulation and re-usability and reduces class bloat and coupling. See this article by Scott Meyers for deeper information (highly regarded for his C++ books that you should definitely read if you want to improve your effective and clean use of C++).
Also note that you should never derive from STL containers. They are not designed as base classes and you might easily invoke undefined behaviour. But see Is there any real risk to deriving from the C++ STL containers? .
I think having a free
std::string toString( const MyList &l );
function is perfectly fine. If you are afraid of name clashes, you can consider a namespace as you said. This function is highly decoupled, and won't be able to tinker with private members of MyList objects (as is the case for a member or a friend function).
The only reason which would justify not making it a free function: you notice that you suddenly need to extend the public interface of MyList a lot just to be able to implement toString properly. In that case, I'd make it a friend function.
If you did something like:
template<typename T>
std::ostream& operator<< (std::ostream &strm, const MyList<T> &list)
{
if (list.empty())
return strm;
MyList<T>::const_iterator iter = list.begin(),
end = list.end();
// Write the first value
strm << *iter++;
while (iter != end)
strm << "," << *iter++;
return strm;
}
Then you would essentially have a to string for anything in the list, as long as the elements implement the streaming operator
Have you considered composition, as opposed to inheritance? i.e. Your MyList has a member variable of type std::vector.
You may complain that you will now need to replicate the API of std::vector in MyList. But you say that you might change the implementation later, so you'll need to do that anyway. You may as well do it straight away, to avoid having to change all the client code later on.
Inheritance is completely wrong in this case.
Global function approach is perfectly fine.
One of 'the ways' in C++ is to overload operator << and use stringstream, for example, to output your vector or something else.
I would go with global template function printOnStream. That way you can easily add support for other data types and using stream is more general than creating a string.
I would not use inheritance because there might be some tricky cases. Basic thing is as you mentioned - lack of virtual destructor. But also everything that expects std::vector won't work properly with your data type - for example you can run into slicing problem.
Why don't your debug and assert methods do this for you?
Say I have a class with a private data member n and a public get_n() function.
When overloading the output operator for example, I can either use get_n() or make it a friend and use n.
Is there a 'best' choice? And if so, why?
Or is the difference going to be optimized away?
Thanks.
Use get_n, since this is not a proper usage of friend. And if get_n is a simple return n, the compiler is most likely going to inline it automatically.
I will answer your question with a question:
Why did you create the public get_n() in the first place?
You've already gotten a lot of somewhat-conflicting answers, so what you undoubtedly need is one more that contradicts nearly all of them.
From an efficiency viewpoint, it's unlikely to make any difference. A function that just returns a value will undoubtedly be generated inline unless you specifically prohibit that from happening by turning off all optimization.
That leaves only a question of what's preferable from a design viewpoint. At least IMO, it's usually preferable to not have a get_n in the first place. Once you remove that design problem, the question you asked just disappears: since there is no get_n to start with, you can't write other code to depend upon it.
That does still leave a small question of how you should do things though. This (of course) leads to more questions. In particular, what sort of thing does n represent? I realize you're probably giving a hypothetical example, but a good design (in this case) depends on knowing a little more about what n is and how it's used, as well as the type of which n is a member, and how it is intended to be used as well.
If n is a member of a leaf class, from which you expect no derivation, then you should probably use a friend function that writes n out directly:
class whatever {
int n;
friend std::ostream &operator<<(std::ostream &os, whatever const &w) {
return os << w.n;
}
};
Simple, straightforward, and effective.
If, however, n is a member of something you expect to use (or be used) as a base class, then you usually want to use a "virtual virtual" function:
class whatever {
int n;
virtual std::ostream &write(std::ostream &os) {
return os << n;
}
friend std::ostream &operator<<(std::ostream &os, whatever const &w) {
return w.write(os);
}
};
Note, however, that this assumes you're interested in writing out an entire object, and it just happens that at least in the current implementation, that means writing out the value of n.
As to why you should do things this way, there are a few simple principles I think should be followed:
Either make something really private, or make it public. A private member with public get_n (and, as often as not, public set_n as well) may be required for JavaBeans (for one example) but is still a really bad idea, and shows a gross misunderstanding of object orientation or encapsulation, not to mention producing downright ugly code.
Tell, don't ask. A public get_n frequently means you end up with client code that does a read/modify/write cycle, with the object acting as dumb data container. It's generally preferable to convert that to a single operation in which the client code describes the desired result, and the object itself does the read/modify/write to achieve that result.
Minimize the interface. You should strive for each object to have the smallest interface possible without causing unduly pain for users. Eliminating a public function like get_n is nearly always a good thing in itself, independent of its being good for encapsulation.
Since others have commented about friend functions, I'll add my two cents worth on that subject as well. It's fairly frequent to hear comments to the effect that "friend should be avoided because it breaks encapsulation."
I must vehemently disagree, and further believe that anybody who thinks that still has some work to do in learning to think like a programmer. A programmer must think in terms of abstractions, and then implement those abstractions as reasonably as possible in the real world.
If an object supports input and/or output, then the input and output are parts of that object's interface, and whatever implements that interface is part of the object. The only other possibility is that the type of object does not support input and/or output.
The point here is pretty simple: at least to support the normal conventions, C++ inserters and extractors must be written as free (non-member) functions. Despite this, insertion and extraction are just as much a part of the class' interface as any other operations, and (therefore) the inserter/extractor are just as much a part of the class (as an abstraction) as anything else is.
I'd note for the record that this is part of why I prefer to implement the friend functions involved inside the class, as I've shown them above. From a logical viewpoint, they're part of the class, so making them look like part of the class is a good thing.
I'll repeat one last time for emphasis: Giving them access to class internals can't possibly break encapsulation, because in reality they're parts of the class -- and C++'s strange requirement that they be implemented as free functions does not change that fact by one, single, solitary iota.
In this case the best practice is for the class to implement a toString method, that the output operator uses to get a string representation. Since this is a member function, it can access all the data directly. It also has the added benefit that you can make this method vritual, so that subclasses can override it, and you only need a single output operator for the base class.
Can the operator be implemented without using friend? Yes- don't use friend. No- make friend.