UE4 class Operator bool() overload - c++

when I go through tutorial here UE4 Basics
I noticed that in CollidingPawn.cpp
A if statement is conditioned on a object if (OurMovementComponent && ...){...}
Which is declared and defined as
class UCollidingPawnMovementComponent* OurMovementComponent;
//...
class HOWTO_COMPONENTS_API UCollidingPawnMovementComponent : public UPawnMovementComponent
{/* ... */};
I think the class have a overloaded () operator, then I trace way back to all its parents, but I could not find one, so I wonder what does the if statement check here, and how it's defined.

OurMovementComponent is defined as a pointer. All pointers can be tested in conditionals, regardless of whether their pointee type has an overloaded operator bool or not.
There is no difference between fundamental types and class types when it comes to pointers to them.
The if statement is checking that the pointer is not null, likely before accessing the object it's supposed to point at, so as to avoid undefined behavior.

Related

What does the .*& operator do? [duplicate]

This question already has an answer here:
I can't understand this line - dereferencing an address of private member variable or what?
(1 answer)
Closed 6 years ago.
I stumbled across this question, which had an answer that used an odd construct:
typedef std::queue<int> Q;
typedef Q::container_type C;
C & get (Q &q)
{
struct hack : private Q {
static C & get (Q &q) {
return q.*&hack::c;
}
};
return hack::get(q);
}
I generally follow that q has access to its own c member that is being referenced by the get function. But, I am at a loss to clearly explain it. What is happening exactly with the .*&, and why is it allowed?
typedef std::queue<int> Q;
Q is a queue adapted container.
typedef Q::container_type C;
C is the underlying container of the Q -- which is a deque<int>.
C & get (Q &q) {
get takes a queue and returns a deque. In fact it returns the deque that the queue wraps: by conventional means, this is not possible.
struct hack : private Q {
hack is a type local to the function. It inherits from Q and has only one static member function. From its name, you may suspect it is a hack. You are right.
No hack is ever instantiated.
static C & get (Q &q) {
hack::get has the same signature as get itself. In fact we delegate all of the work of get to this method.
return q.*&hack::c;
this line needs to be broken down. I will do it in more lines:
using mem_ptr_t = C Q::*; // aka typedef C Q::*mem_ptr_t;
mem_ptr_t c_mem_ptr = &hack::c;
C& ret = q.*c_mem_ptr;
return ret;
The first line defines the type of a member pointer to a field of type C within a Q. Both the C++11 and C++03 ways of naming this type are ugly.
The second line gets a member pointer to the field c in Q. It does this through the hole in the type system of C++. &hack::c is logically of type C hack::* -- a pointer to a member of type C within a class of type hack. In fact, that is why we can access it in a static member of hack. But the c in question is actually in Q, so the actual type of the expression in C++ is C Q::*: a pointer to a member variable of Q.
You cannot directly get this member pointer within hack -- &Q::c is illegal, but &hack::c is not.
You can think of member pointers as 'typed offsets' into another type: &hack::c is the "offset" of c within Q together with knowing it is of type C. Now this isn't really true -- it is some opaque value that tells the compiler how to get c from Q -- but it helps to think about it that way (and it may be implemented that way in simple cases).
We then use this member pointer together with a Q& to get the c out of the Q. Getting a member pointer is constrained by protected: using it is not! The way we do it is with operator .*, which is the member dereference operator, which you can pass either member function pointers or members on the right, and class instances on the left.
instance .* member_ptr is an expression that finds the member "pointed to" by member_ptr within the instance. In the original code, everything was done on one line:
instance .* &class_name::member_name
so it looked like there was an operator .*&.
}
};
and then we close up the static method and hack class, and:
return hack::get(q);
}
call it. This technique gives access to protected state: without it, protected members can only be accessed in child classes of the same instance. Using this, we can access protected members of any instance, without violating any bit of the standard.
It's a hack, as the nomenclature indicates.
.* takes an object on the left side, and a member pointer on the right side, and resolves the pointed-to member of the given object. & is, of course, the referencing operator; &Class::Member returns a member pointer, which cannot by itself be dereferenced but which can be used with the .* and ->* operators (the latter being the wackiest of all C++ operators). So obj .* &Class::Member has exactly the same effect as obj.Member.
The reason this more complicated version is being used comes down to a loophole in protection semantics; basically, it allows access to protected members of a base class object, even if the object is not of the same type as the class doing this dirty hack.
Personally, I think the trick is too clever by half. I'd ordinarily* write such code as:
struct hack : private Q {
static C & get (Q &q) {
return static_cast<hack &>(q).c;
}
};
Which is technically slightly less safe, but doesn't obscure what's going on.
.* Well, ordinarily I'd avoid writing such a thing at all. But I literally did this earlier today, so I can't really throw stones.

C++ User Defined Class Copy Assignment Missing?

I have written two custom classes, called A and B
My B class has a member variable a, and it has a function:
void B::setA(A s)
{
a = s;
}
However, this line is giving me an error:
'operator =' function is unavailable in 'A'.
From my understanding, this means somehow the compiler is not creating a default copy assignment function for my A class. However, I don't see why... the only constructor I've written in A looks like...
class A
{
//...
public:
A() {};
//...
};
Now in truth, A and B are large classes with a lot of member variables, and the names aren't really A and B. Short of posting the entire source for both of these classes, could anyone tell me what types of things I might look for when trying to diagnose that error message? Just to be clear, I never use pointers or low-level features like that so, as far as I know, the default copy-assignment should work fine for class A.
edit:
Someone mentioned that one of the member variables of A might be to blame, so here are all of the types:
const std::string
static const bool
static std::map<int,std::string>
std::vector
std::map<int, C>
where C is a struct that I defined in the same header file that A is in. It just contains a few integers and strings.
You have in class A a non-static data member declared as
const std::string
that is with the qualifier const. In this case the implicit copy assignment operator is defined by the compiler as deleted.
const members don't mix well with copy assignment operators. Not only won't the compiler generate one for you, it would also be semantically hard to come up with an "assignment" which does not actually assign everything.
Nothing stops you from writing an assignment operator which does not assign to your const member, of course, but that would mean one of two things:
The assigned object does not appear to the client as an identical copy of the source, which is not what one would except from a copy assignment operator, so that would be a case of operator-overloading abuse.
The member variable does not have an observable effect to the outside. In that case, one must wonder why it exists in the first place, or rather why it is not mutable rather than const.

When an object provides both `operator!` and `operator bool`, which is used in the expression `!obj`?

I've ran across a question I am not able to answer for myself. Also, I didn't find an answer to this on both google and here. Say, I want to "check an object for validity" in an if clause, like so:
MyClass myObject;
// [some code, if any]
if (!myObject)
{
// [do something]
}
Let MyClass be defined something like this:
class MyClass
{
public:
MyClass() { };
virtual ~MyClass() { };
bool operator!()
{
return !myBool;
};
operator bool()
{
return myBool;
};
private:
bool myBool = 0;
};
My question now is: Which one of the overloaded operators is actually used in this if clause? Either way, the result is obviously the same.
It will use operator!.
A function whose parameter types match the arguments will be chosen in preference to one that requires type conversions.
You'll find that operator ! gets executed because it's the most direct resolution. If it used operator bool instead then it would have to call the conversion operator first, and then apply the ! separately to that.
As a general rule, it's a good idea to avoid that situation though. It's generally better just to define the bool conversion, because strictly speaking that's what you want your logical operators to act on, rather than MyClass directly. Defining both creates a bit of a readability problem, and is a form of redundant code duplication (which can lead to programmer error in future).

The Arrow Member Operator in C++

I am quite new to using C++. I have handled Java and ActionScript before, but now I want to learn this powerful language. Since C++ grants the programmer the ability to explicitly use pointers, I am quite confused over the use of the arrow member operator. Here is a sample code I tried writing.
main.cpp:
#include <iostream>
#include "Arrow.h"
using namespace std;
int main()
{
Arrow object;
Arrow *pter = &object;
object.printCrap(); //Using Dot Access
pter->printCrap(); //Using Arrow Member Operator
return 0;
}
Arrow.cpp
#include <iostream>
#include "Arrow.h"
using namespace std;
Arrow::Arrow()
{
}
void Arrow::printCrap(){
cout << "Steak!" << endl;
}
In the above code, all it does is to print steak, using both methods (Dot and Arrow).
In short, in writing a real practical application using C++, when do I use the arrow notation? I’m used to using the dot notation due to my previous programming experience, but the arrow is completely new to me.
In C, a->b is precisely equivalent to (*a).b. The "arrow" notation was introduced as a convenience; accessing a member of a struct via a pointer was fairly common and the arrow notation is easier to write/type, and generally considered more readable as well.
C++ adds another wrinkle as well though: operator-> can be overloaded for a struct/class. Although fairly unusual otherwise, doing so is common (nearly required) for smart pointer classes.
That's not really unusual in itself: C++ allows the vast majority of operators to be overloaded (although some almost never should be, such as operator&&, operator|| and operator,).
What is unusual is how an overloaded operator-> is interpreted. First, although a->b looks like -> is a binary operator, when you overload it in C++, it's treated as a unary operator, so the correct signature is T::operator(), not T::operator(U) or something on that order.
The result is interpreted somewhat unusually as well. Assuming foo is an object of some type that overloads operator->, foo->bar is interpreted as meaning (f.operator->())->bar. That, in turn, restricts the return type of an overloaded operator->. Specifically, it must return either an instance of another class that also overloads operator-> (or a reference to such an object) or else it must return a pointer.
In the former case, a simple-looking foo->bar could actually mean "chasing" through an entire (arbitrarily long) chain of instances of objects, each of which overloads operator->, until one is finally reached that can refer to a member named bar. For an (admittedly extreme) example, consider this:
#include <iostream>
class int_proxy {
int val;
public:
int_proxy(): val(0) {}
int_proxy &operator=(int n) {
std::cout<<"int_proxy::operator= called\n";
val=n;
return *this;
}
};
struct fubar {
int_proxy bar;
} instance;
struct h {
fubar *operator->() {
std::cout<<"used h::operator->\n";
return &instance;
}
};
struct g {
h operator->() {
std::cout<<"used g::operator->\n";
return h();
}
};
struct f {
g operator->() {
std::cout<<"Used f::operator->\n";
return g();
}
};
int main() {
f foo;
foo->bar=1;
}
Even though foo->bar=1; looks like a simple assignment to a member via a pointer, this program actually produces the following output:
Used f::operator->
used g::operator->
used h::operator->
int_proxy::operator= called
Clearly, in this case foo->bar is not (even close to) equivalent to a simple (*foo).bar. As is obvious from the output, the compiler generates "hidden" code to walk through the whole series of overloaded -> operators in various classes to get from foo to (a pointer to) something that has a member named bar (which in this case is also a type that overloads operator=, so we can see output from the assignment as well).
Good Question,
Dot(.) this operator is used for accessing the member function or
sometime the data member of a class or structure using instance
variable of that class/Structure.
object.function();
object.dataMember; //not a standard for class.
arrow(->) this operator is used for accessing the member function or
sometime the data member of a class or structure but using pointer of
that class/Structure.
ptr->function();
ptr->datamember; //not a standard for class.
The -> operator is a way of calling a member function of the pointer that is being dereferenced. It can also be written as (*pter).printCap(). C++ is difficult to learn without a class or book so I recommend getting one, it'll be a great investement!

How to convert this VC++ 6 code to VC++ 2008?

Forgive me my C++ is incredibly rusty. But I am trying to take some old code and recompile it under Visual C++ 2008. It was originally written for Visual C++ 6.0
The error I am getting is this:
error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
Ok seems simple enough. But then I look at the offending line of code:
operator=(int i) {SetAsInt(i);};
And it appears the type IS declared. So what am I missing?
FOLLOW UP:
I took Micheals advice and added a return type of the function (the class), and added return this; to the end of each. Then I ran across this:
operator=(const CString& str);
There is no function body defined... what exactly does this mean?
You need to have the operator=() method return something (it would assume int if the diagnostic weren't an error, as the error message somewhat confusingly indicates).
Generally it would be a reference to the object the operator is working on so the assignments can be chained as in a normal assignment expression. Something like:
// where T is the class for this operator= implementation
T& operator=( int i) {
// ...
return *this;
}
As michael has said, operator= needs a return type, but this type can be void:
class A {
...
void operator = ( int i ) {
SetAsInt(i);
}
};
although this means you won't be able to "daisy-chain" assignments.
Regarding the follow-up, it's probably saying that assignment for the class is forbidden:
class B {
private:
void operator =( const B & );
};
Making the assignment op (and usually the copy ctor) private and then not implementing them means it is impossible to assign (or copy) class instances, which is desirable behaviour for most business -oriented classes.
For your second question, the declaration is likey being used to prevent copying the object.
From the C++ Reference Guide by Danny Kalev
Question: How Can I Prevent
Object-Copying?
Answer: Declare the copy constructor
and the assignment operator as private
members, without defining them. Any
statement that involves direct or
indirect copying of that class will
cause a compilation error. This
technique isn’t exactly the picture of
elegance, but in contemporary C++
there’s no other way to block copying
inexpensively.
Regarding your edit:
It simply means that the function has been declared, but not defined. The compiler knows it exists, so it is legal to call it. But it will generate a linker error, unless the compiler is actually able to find the body somewhere.
Typically, you define the function in a header file, and then in the .cpp file, you have something like
// Assuming the class it is a member of is called Foo
Foo& Foo::operator=(const CString& str) {
...
}
The only thing to note here is the Foo:: prefix. Because this definition is outside the class definition itself, we have to use this prefix to specify that the operator= we're defining belongs to the Foo class.
returning ANYTHING but an lval is typically wrong and is only used in very special situations
certainly returning a const reference precludes assignment chaining (a=(b=c)), and part of the point of operators is to make classes behave like built in types
Well, that's an assignment operator. It helps one define how other objects (both of the same and other types) are assigned to an instance of the class it is defined within.
The correct syntax is (assuming your class is called 'Object'):
const Object& operator=(const Object& other)
{
// copy members, one at a time.
this->member1 = other.member1;
return *this;
}
Notice the return type is constant. This is a to avoid semantically incorrect, syntactically correct statements such as:
Object A, B, C;
(A = B) = C;
If you define the return type as constant, the above code will not compile (reasonable enough, since it's really messed up) while leaving out the const will allow such bad code to compile, and of course someone will pull their hair trying to figure out what's wrong.
P.S. You might want to think it through: what would happen if you leave out the const from the return type and execute the (A = B) = C; code?
Regarding the follow-up question, the return type can be anything in this case. However, since most assignment operators return a reference to the class in which they are declared, it would be best to return just that, in order not to confuse the reader.
CString& operator=(const CString& str);
Presumably, this function is declared in the private section of the class. This is the standard idiom to make objects of the class non-assignable.