"Explicit" preventing automatic type conversion? [duplicate] - c++

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What does the explicit keyword in C++ mean?
I do not understand the following. If I have:
class Stack{
explicit Stack(int size);
}
without the keyword explicit I would be allowed to do:
Stack s;
s = 40;
Why would I be allowed to do the above if explicit wasn't provided?? Is it because this is stack-allocation (no constructor) and C++ allows anything to be assigned to the variable unless explicit is used?

This line
s = 40;
is equivalent to
s.operator = (40);
Which tries to match the default operator = (const Stack &). If the Stack constructor is not explicit, then the following conversion is tried and succeeds:
s.operator = (Stack(40));
If the constructor is explicit then this conversion is not tried and the overload resolution fails.

hey its pretty simple .
the explicit key word only stops complier from automatic conversion of any data type to the user defined one.. it is usually used with constructor having single argument .
so in this case u are jus stopping the complier from explicit conversion
#include iostream
using namespace std;
class A
{
private:
int x;
public:
A(int a):x(a)
{}
}
int main()
{
A b=10; // this syntax can work and it will automatically add this 10 inside the
// constructor
return 0;
}
but here
class A
{
private:
int x;
public:
explicit A(int a):x(a)
{}
}
int main()
{
A b=10; // this syntax will not work here and a syntax error
return 0;
}

Related

Const after operator function c++ [duplicate]

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.

C++ - Unable to overload assignment operator [duplicate]

This question already has answers here:
The assignment operator and initialization
(2 answers)
Closed 6 years ago.
I am trying to overload the assignment operator but it doesn't seem to work. The code is based on this answer. I've searched for other examples of overloading the assignment operator, but it doesn't seem like my code shouldn't run.
This is my code:
#pragma once
#include <assert.h>
class ReadOnlyInt
{
public:
ReadOnlyInt(): assigned(false) {}
ReadOnlyInt& operator=(int v);
operator int() const ;
private:
int value;
bool assigned;
};
ReadOnlyInt& ReadOnlyInt::operator=(int v)
{
assert(!assigned);
value = v;
assigned = true;
return *this;
}
ReadOnlyInt::operator int() const
{
assert(assigned);
return value;
}
Intellisense doesn't give any warnings, but the operator= is not highlighted as a keyword.
Now if I make an assigment, Intellisense does recognize it's not possible:
ReadOnlyInt bar = 12;
no suitable constructor exists to convert from "int" to "ReadOnlyInt"
This works however:
int foo = bar;
Solution
This question was marked as duplicate, so I can't answer it. This was the solution I came up with based on the comments and answer on this question:
ReadOnlyInt::ReadOnlyInt()
: assigned(false)
{}
ReadOnlyInt::ReadOnlyInt(int v)
: value(v), assigned(true)
{}
You can't initialize and declare at the same time. You need to do this
ReadOnlyInt bar;
bar = 12;
This is because there is no appropriate constructor for ReadOnlyInt that takes an int argument.

Initializing A Variable With Its Default Constructor

Question:
Is there a difference between the following initializations?
(A) What exactly is the second one doing?
(B) Is one more efficient than the other?
int variable = 0;
int variable = int();
This question also applies to other data types such as std::string:
std::string variable = "";
std::string variable = std::string();
Background:
I basically got the idea here (the second code sample for the accepted answer) when I was trying to empty out a stringstream.
I also had to start using it when I began learning classes and realized that member variable initializations had to be done in the constructor, not just following its definition in the header. For example, initializing a vector:
// Header.h
class myClass
{
private:
std::vector<std::string> myVector;
};
// Source.cpp
myClass::myClass()
{
for (int i=0;i<5;i++)
{
myVector.push_back(std::string());
}
}
Any clarity on this will be greatly appreciated!
Edit
After reading again, I realized that you explicitely asked about the default constructor while I provided a lot of examples with a 1 parameter constructor.
For Visual Studio C++ compiler, the following code only executes the default constructor, but if the copy constructor is defined explicit, it still complains because the never called copy constructor can't be called this way.
#include <iostream>
class MyInt {
public:
MyInt() : _i(0) {
std::cout << "default" << std::endl;
}
MyInt(const MyInt& other) : _i(other._i) {
std::cout << "copy" << std::endl;
}
int _i;
};
int main() {
MyInt i = MyInt();
return i._i;
}
Original (typo fixed)
For int variables, there is no difference between the forms.
Custom classes with a 1 argument constructor also accept assignment initialization, unless the constructor is marked as explicit, then the constructor call Type varname(argument) is required and assignment produces a compiler error.
See below examples for the different variants
class MyInt1 {
public:
MyInt1(int i) : _i(i) { }
int _i;
};
class MyInt2 {
public:
explicit MyInt2(int i) : _i(i) { }
int _i;
};
class MyInt3 {
public:
explicit MyInt3(int i) : _i(i) { }
explicit MyInt3(const MyInt3& other) : _i(other._i) { }
int _i;
};
int main() {
MyInt1 i1_1(0); // int constructor called
MyInt1 i1_2 = 0; // int constructor called
MyInt2 i2_1(0); // int constructor called
MyInt2 i2_2 = 0; // int constructor explicit - ERROR!
MyInt2 i2_3 = MyInt2(0); // int constructor called
MyInt3 i3_1(0); // int constructor called
MyInt3 i3_2 = 0; // int constructor explicit - ERROR!
MyInt3 i3_3 = MyInt3(0); // int constructor called, copy constructor explicit - ERROR!
}
The main difference between something like:
int i = int(); and int i = 0;
is that using a default constructor such as int() or string(), etc., unless overloaded/overridden, will set the variable equal to NULL, while just about all other forms of instantiation and declarations of variables will require some form of value assignment and therefore will not be NULL but a specific value.
As far as my knowledge on efficiency, neither one is "better".

How can I prevent implicit conversion from char to int?

I have the following code:
#include <iostream>
template<typename T> class DynArray
{
T *contents;
int size;
public:
explicit DynArray(int initial_size);
};
int main()
{
DynArray<std::string> b('7');
return 0;
}
My question is: how can I prevent the implicit conversion from char to int from compiling? (i.e. this line: `DynArray b('7');
You can't directly, but you can make an overload of the constructor which gets chosen first when passed a char...
explicit DynArray(char);
Make it private and don't define it, just declare it. The same as declaring but not defining a copy ctor/copy assignment operator to prevent a class from being copyable.
Or, with C++11, make it deleted (which is the new cleaner/clearer/better way of doing the above)...
explicit DynArray(char) = delete;

Assignment vs Initialization in C++

I thought that constructors control initialization and operator= functions control assignment in C++. So why does this code work?
#include <iostream>
#include <cmath>
using namespace std;
class Deg {
public:
Deg() {}
Deg(int a) : d(a) {}
void operator()(double a)
{
cout << pow(a,d) << endl;
}
private:
int d;
};
int
main(int argc, char **argv)
{
Deg d = 2;
d(5);
d = 3; /* this shouldn't work, Deg doesn't have an operator= that takes an int */
d(5);
return 0;
}
On the third line of the main function, I am assigning an int to an object of class Deg. Since I don't have an operator=(int) function, I thought that this would certainly fail...but instead it calls the Deg(int a) constructor. So do constructors control assignment as well?
This is what's called implicit type conversion. The compiler will look to see if there's a constructor to directly change from the type you're assigning to the type you're trying to assign, and call it. You can stop it from happening by adding the explicit keyword in front of the constructor you wouldn't like to be implicitly called, like this:
explicit Deg(int a) : d(a) {}
Just to clarify JonM's answer:
For the line d = 3, an assignment operator is involved. 3 is being implicitly converted to a Deg, as JonM said, and then that Deg is assigned to d using the compiler-generated assignment operator (which by default does a member-wise assignment). If you want to prevent assignment, you must declare a private assignment operator (and do not implement it):
//...
private:
Deg& operator=(const Deg&);
}