This question already has answers here:
"const T &arg" vs. "T arg"
(14 answers)
What are the differences between a pointer variable and a reference variable?
(44 answers)
Closed 7 years ago.
// const objects
#include <iostream>
using namespace std;
class MyClass {
int x;
public:
MyClass(int val) : x(val) {}
const int& get() const {return x;}
};
void print (const MyClass& arg) { // Need to understand this line
cout << arg.get() << '\n';
}
int main() {
MyClass foo (10);
print(foo);
return 0;
}
I am new to C++. Need to understand what are the parameters passed in print function. If this is address then why are we passing foo is print function call.
The & in void print (const MyClass& arg) that arg is passed by reference. It is C++s way to make pointers and things a little bit easier.
References allow you to manipulate a variable inside of a function and make the results visible on the outside too. So a bit like pointers. But you don't need to explicitly get the address of the variable to do that.
The const statement is a way to prevent the described behavior. const forbids the manipulation of arg inside print.
Related
This question already has answers here:
Why {} is better candidate to be int than string for C++ overload resolution? [duplicate]
(1 answer)
Overload resolution with an empty brace initializer: pointer or reference? [duplicate]
(1 answer)
Closed 4 months ago.
In this code:
#include <string>
#include <iostream>
void my_function(const char* value)
{
std::cout << "char * " << (value ? value : "nullptr");
}
void my_function(const std::string &value)
{
std::cout << "string";
}
int main()
{
my_function({});
}
https://godbolt.org/z/56bxzjM1M
The const char * overload is chosen, passing a nullptr pointer. Can somebody explain why? I assume this is something weird with initializer lists? (By the way, this happens with my_function(string value) too, so it isn't the reference).
This caused a crash in our code because somebody added a const char * overload, causing the rare caller who passed {} to send in a nullptr.
This question already has answers here:
Meaning of 'const' last in a function declaration of a class?
(12 answers)
Closed last year.
I'm learning C++ i saw a const after an operator function.
It doesn't make sense because the function returns the same value regardless of the const.
What's the purpose of using it?
using namespace std;
class Person {
public:
int age;
Person(int age) : age(age) {}
int operator *(int &b) const {
return b;
}
};
int main() {
Person *p = new Person(11);
int a = 19;
cout << *p * a; // prints 19
delete p;
}
A const operator behind a member function applies to the this pointer, i.e. it guarantees that the object you call this function on may not be changed by it. It's called a const-qualified member function
If you tried, in this example, to change the persons age in the openrator*(), you would get a compile error.
This question already has answers here:
How do I remove code duplication between similar const and non-const member functions?
(21 answers)
Closed 2 years ago.
class MyClass {
public:
void Bar()const
{
std::cout << "A::Bar() const\n";
}
void Bar()
{
std::cout << "A::func()\n";
//call Bar()const in here
}
};
I would like to know how i should call Bar()const member function in Bar() member function?
You need to cast the object to a const qualified version to call the const function. That would look like
void Bar()
{
std::cout << "A::func()\n";
const_cast<const MyClass&>(*this).Bar(); // calls const version
}
This question already has answers here:
What is the meaning of & in c++?
(6 answers)
Closed 4 years ago.
#include <iostream>
using namespace std;
class Dummy {
public:
bool isitme (Dummy& param);
};
bool Dummy::isitme (Dummy& param)
{
if (¶m == this) return true;
else return false;
}
int main () {
Dummy a;
Dummy* b = &a;
if ( b->isitme(a) )
cout << "yes, &a is b\n";
return 0;
}
I was looking at this C++ example and I don't understand why bool isitme (Dummy& param); uses the dereferencing sign '&'. The argument is an Dummy object itself right, why it is the object's address?
Ampersand is not the "dereferencing sign". It is used here in two different ways which I will explain below.
The "dereference sign" is asterisk (*).
bool Dummy::isitme (Dummy& param)
Here, Dummy& param means that param is a reference to a Dummy object.
if (¶m == this) return true;
Here, ¶m denotes address of param.
The isitme takes its argument by reference that is it takes the address of the object instead of copying it. The point is not to copy the object and to work on the original one.
This question already has answers here:
What is a lambda expression in C++11?
(10 answers)
Closed 6 years ago.
What's the correct way to have an anonymous local function object access an argument of the containing method? I.e., what's the correct way to do the following:
void A::foo(B& b)
{
struct {
void operator()() {b.bar();}
} func;
func();
}
NB: This example is contrived for simplicity: the actual use-case involves applying an anonymous local function object to each element in a container to have the element act on the argument of the containing method.
You need to pass the reference/pointer of the worked-on object to the anonymous one. But since it's anonymous, you cannot declare its constructor. If you named it, you'd be able to say:
void A::foo(B& b)
{
struct Foo{
B& b;
Foo(B& b) : b(b) {}
void operator()() {b.bar();}
} func{b};
func();
}
That being said, in C++11 - as you tagged this question - you could use a lambda expression:
void A::foo(B& b)
{
auto func = [&]{ b.bar(); };
func();
}
A function cannot access stuff from its local scope.
Lambdas get around that by capturing variables in their local scope. They copy/move/reference them. But they're not technically accessing those variables. Only lambdas can do this.
You can of course explicitly do what a lambda does implicitly. That is, have the class's constructor take a copy or reference to a variable, then initialize the object by calling that constructor. Of course, that means it cannot be an anonymous class anymore.
In fact you wrote almost all correctly. Here you are
#include <iostream>
struct A
{
void foo( const struct B &b );
};
struct B
{
void bar() const { std::cout << "Hello A!" << std::endl; }
};
void A::foo( const B &b )
{
struct
{
void operator ()( const B &b ) const { b.bar(); }
} func;
func( b );
};
int main()
{
A().foo( B() );
return 0;
}
The program output is
Hello A!
A more simpler way to define a functional object is to use lambda expressions.