Type casting a custom c++ class - c++

If I have my own SString class in c++ and I want to be able to do this:
SString x("text");
LPCSTR p = (LPCSTR)x;
cout<<p;
How do I do it?

Create conversion operator to LPCSTR in your class SString. If you can use C++11 this operator should be explicit.
operator LPCSTR() const { /*return data*/ };
Also you can create some function like (i think this variant is better, than conversion operator)
LPCSTR asLPCSTR() const { /*return data*/ };

In addition to what ForEveR said, note that you can also overload
ostream& operator << (ostream& str, const SString& ss);
and call
cout<<x;
directly.

Related

Overloading the comparison operator for object members

Say I have a class called book:
class Book {
int i;
public:
Book(int ii)
: i(ii) {
}
int ISBN() {
return i;
}
};
I want to overload the comparison operator for the Book class, so that I can create a bool function that will compare the member "i" when it comes across book1==book2.
bool is_same() {
return (book1==book2) ? true : false;
}
How would I go about this? This is the current operator overload function I have, it gives me an "invalid initialization of non-const reference of type 'Book&' from an rvalue of the type 'bool'" error. I currently have my overloaded function inside of the class Book as a public function.
Book& operator==(const Book& b) const {
return ISBN() == b.ISBN();
}
I'm relatively new to operator overloading, I have sifted through many answers but none of them resolve my issue. I understand how one could simply do book1==book2, but that would only return true if every single member was of the same value. In this case I have more than just one, but I only want to return true if "i" is the same for both objects.
You basically have 2 choices:
use a member operator with one argument:
class Book {
...
bool operator==( const Book &an ) const { return ISDN() == an.ISDN(); }
};
use a non-member operator (and possibly a friend statement) with 2 arguments:
bool operator==( const Book &b1, const Book &b2 )
{
return b1.ISBN() == b2.ISBN();
}
Note that ISDN() should be made const.
Either way, you need to return a bool, not a Book &, which is usually returned by the assignment operator =, not the comparison operator ==.

Can I prevent comparison to NULL with overloaded operator==?

Let's say I have a String class that I want to be able to construct or assign with a pointer, but disallow compiling with an explicit std::nullptr assignment:
class String {
public:
String(const char *);
friend bool operator== (const String &, const char *);
friend bool operator!= (const String &, const char *);
// some important things left out
private:
String(std::nullptr_t);
}
The purpose is to give "error: 'operator=' is a private member of 'String'" if I try to write "str = NULL", which helps me identify some bugs in an old codebase. Obviously, the public constructor should handle the nullptr case as well. Additionally, it helps me identify some similar issues such as "str = 0", which the compiler will report as ambiguous.
My question is - can I do something similar with binary comparison operators, operator== and operator!=? I would like the compiler to report an attempted comparison to std::nullptr_t, which is also very common in my codebase.
Whenever you want to prohibit calling a certain function you can append = delete, which was introduced in C++11:
friend bool operator==(const String&, std::nullptr_t) = delete;
friend bool operator!=(const String&, std::nullptr_t) = delete;
Whenever you try to compare your type with nullptr you get this compiler error:
function "operator==(const String &, std::nullptr_t)" cannot be referenced -- it is a deleted function

Make a C++ overloaded operator a function pointer

Is there a way to overload an operator (specifically, operator >>) as a function pointer and then assign it a function at run-time? I want to be able to look at a file at run-time to ascertain the format of the file, then assign the correct function pointer to the operator to make it work as desired. I would assign the correct function in the constructor, before the operator would be called. I realize there are other (perhaps easier) ways to do the same thing, but I'm wondering if this is possible.
Here's what I tried:
bool Flag; // In global scope - set in main()
class MyClass
{
private:
int data;
friend istream & function1(istream & in, MyClass & c);
friend istream & function2(istream & in, MyClass & c);
public:
MyClass() :data(0) {operator>>=((Flag)?&function1:&function2);}
friend istream& (*operator>>)(istream & in, C & c);
};
// function1 and function2 definitions go here
int main (int argc, char **argv)
{
if (argc > 2)
Flag = ((atoi(argv[1]) > 1) ? 1 : 0);
MyClass mcInstance;
ifstream in(argv[2]);
in >> mcInstance;
return 0;
}
I get an error that looks like this:
error: declaration of ‘operator>>’ as non-function
You can't redefine the meaning of any actual function, including operators, at run-time directly: functions are immutable entities. What you can do, however, is to delegate within the function, including a user-defined operator, to a different function using a pointer to a function. For example:
std::istream&
std::operator>> (std::istream& in, MyClass& object) {
return Flag? function1(in, object): function2(in, object);
}
If you want to delegate through a function pointer, e.g., per object, you could set the function pointer up in your object and delegate through that:
class MyClass {
fried std::istream& operator>> (std::istream&, Myclass&);
std::istream& (*d_inputFunction)(std::istream&, MyClass&);
public:
MyClass(): d_inputFunction(Flag? &function1: &function2) {}
// ...
};
std::istream& operator>> (std::istream& in, MyClass& object) {
return (object.d_inputFunction)(in, object);
}

How do I make a class in C++, when initialized, return a boolean value when its name is invoked, but no explicit function call make, like ifstream

How do I make a class in C++, when initialized, return a Boolean value when its name is invoked, but no explicit function call make, like ifstream. I want to be able to do this:
objdef anobj();
if(anobj){
//initialize check is true
}else{
//cannot use object right now
}
not just for initialization, but a check for its ability to be used.
The way istream does it is by providing an implicit conversion to void*
http://www.cplusplus.com/reference/iostream/ios/operator_voidpt/
stream output and implicit void* cast operator function invocation
Update In reaction to the comments, the Safe Bool Idiom would be a far better solution to this: (code directly taken from that page)
class Testable {
bool ok_;
typedef void (Testable::*bool_type)() const;
void this_type_does_not_support_comparisons() const {}
public:
explicit Testable(bool b=true):ok_(b) {}
operator bool_type() const {
return ok_==true ?
&Testable::this_type_does_not_support_comparisons : 0;
}
};
template <typename T>
bool operator!=(const Testable& lhs,const T& rhs) {
lhs.this_type_does_not_support_comparisons();
return false;
}
template <typename T>
bool operator==(const Testable& lhs,const T& rhs) {
lhs.this_type_does_not_support_comparisons();
return false;
}
The article by Bjorn Karlsson contains a reusable implementation for the Safe Bool Idiom
Old sample:
For enjoyment, I still show the straight forward implementation with operator void* overloading, for clarity and also to show the problem with that:
#include <iostream>
struct myclass
{
bool m_isOk;
myclass() : m_isOk(true) { }
operator void* () const { return (void*) (m_isOk? 0x1 : 0x0); }
};
myclass instance;
int main()
{
if (instance)
std::cout << "Ok" << std::endl;
// the trouble with this:
delete instance; // no compile error !
return 0;
}
This is best accomplished using the safe bool idiom.
You provide an implicit conversion to a member-function-pointer, which allows instances of the type to be used in conditions but not implicitly convertyed to bool.
You need a (default) constructor and an operator bool()().
class X {
public:
operator bool ()const{
//... return a boolean expression
}
};
usage:
X x; // note: no brackets!
if( x ) {
....
}
You'll want to create an operator bool function (or as boost does, an unspecified_bool_type that has certain improved properties I can't recall offhand). You may also want to create operator! (For some reason I seem to recall iostreams do this too).

Why is "operator bool()" invoked when I cast to "long"?

I have the following class:
class MyClass {
public:
MyClass( char* what ) : controlled( what ) {}
~MyClass() { delete[] controlled; }
operator char*() const { return controlled; }
operator void*() const { return controlled; }
operator bool() const { return controlled != 0; }
private:
char* controlled;
};
This is compiled with Microsoft SDK that has the following typedefs:
typedef long LONG_PTR;
typedef LONG_PTR LPARAM;
The calling code does the following:
MyClass instance( new char[1000] );
LPARAM castResult = (LPARAM)instance;
// Then we send message intending to pass the address of the buffer inside MyClass
::SendMessage( window, message, wParam, castResult );
Suddenly castResult is 1 - MyClass::operator bool() is invoked, it returns true which is converted to 1. So instead of passing the address I pass 1 into SendMessage() which leads to undefined behaviour.
But why is operator bool() invoked in the first place?
It's one of the known pitfalls of using operator bool, that is a aftershock of C inheritance. You'd definitively benefit from reading about the Safe Bool Idiom.
In general, you didn't provide any other matchable casting operator, and bool (unfortunately) is treated as a good source for arithmetic casting.
operator bool is the best match, because char* and void* can't be converted to long without an explicit cast, unlike bool:
long L1 = (void*)instance; // error
long L2 = (char*)instance; // error
long L3 = (bool)instance; // ok
You cannot implicitly cast a T* to long. But you can cast a bool to long.
So the operator bool is used.
You have to define a operator LPARAM.