C++ can't implement default constructor - c++

I have the following class:
class Fraction {
private:
int x;
int y;
public:
// Constructors
Fraction(long x = 0, long y = 1);
Fraction(const Fraction&)=default;//here is the problem
virtual ~Fraction();
};
I'm trying to disable default C++ constructor to implement my own (I intend to use it for copy). So, I declared it as a default. But, when I'm trying to implement it:
Fraction::Fraction(const Fraction&){}
Compiler throws the following error at me:
./src/Fraction.cpp:16:1: error: definition of explicitly-defaulted
‘Fraction::Fraction(const Fraction&)’ Fraction::Fraction(const
Fraction&){ ^ In file included from ../src/Fraction.cpp:8:0:
../src/Fraction.h:22:2: error: ‘Fraction::Fraction(const Fraction&)’
explicitly defaulted here Fraction(const Fraction&)=default;
Is there any way to fix it? What I'm doing wrong ? I found some articles about defaults, but nothing that can help me fix these errors.

= default tells the compiler to use the default implementation. This also means that you cannot provide your own. If you don't want the compiler to create one, simply remove = default:
class Fraction {
// ...
Fraction(const Fraction&); // NO =default
};
By the way, the "default constructor" is the one that's called when you don't provide any arguments, e.g.
Fraction my_frac; // default constructor called
If you want to disable the default constructor, use =delete:
class Fraction{
public:
Fraction() = delete;
}
Keep in mind that your current Fraction(long, long) provides default arguments, so it's eligible as a default constructor.

Related

C++ : What is wrong with my class constructors ? (no default constructor exists &/or conflicting declaration)?

Trying to write a simple exponential filter class, self contained in a .h file.
I'm getting these errors:
no default constructor exists for class "ExpoFilter"
conflicting declaration 'ExpoFilter alpha_temp'
I don't understand the problem, I have 2 constructors, one for an int type parameter and one for a float type parameter. Isn't that enough to be considered 2 different function signatures?
I am also calling the first constructor from within the second one, which I've done successfully in the past. Also tried proper full .cpp + .h file without success.
So what is wrong?
Here is the code:
/*
Exponential filter, a.k.a exponential moving average, object Class
*/
#ifndef ExpoFilter_h
#define ExpoFilter_h
class ExpoFilter
{
// user-accessible "public" interface
public:
// Constructors
ExpoFilter::ExpoFilter(float alpha){
_alpha = alpha;
_alpha2 = 1.0f - _alpha;
}
ExpoFilter::ExpoFilter(int N){
float alpha_temp = 2.0f / (N + 1);
ExpoFilter(alpha_temp);
}
ExpoFilter::operator float(){
return _value;
}
float ExpoFilter::operator=(float newValue)
{
return NewValue(newValue);
}
float ExpoFilter::NewValue(float newValue){
_value = newValue * _alpha + _value * _alpha2;
return _value;
}
// library-accessible "private" interface
private:
float _alpha;
float _alpha2;
float _value;
};
#endif
The problem is that since you have a parameterized constructor for your class ExpoFilter, the compiler will not synthesize the default constructor ExpoFilter::ExpoFilter() by itself. This means that if you want to create/construct an object of class ExpoFilter using the default constructor, say by writing ExpoFilter alpha_temp;, then the compiler will produce error because there is no default constructor.
To solve this you must add a default constructor for your class as shown below:
class ExpoFilter
{
//other code here as before
//default constructor that uses constructor initializer list
ExpoFilter() : _alpha(0), _alpha2(0), value(0)
{
}
}
Now, when you wrote:
ExpoFilter(alpha_temp); //this creates a temporary object named alpha_temp using the default constructor
The above statement creates an object of type ExpoFilter named alpha_temp using the default constructor. But since the compiler did not synthesize a default ctor, you will get the mentioned error.
If your intention was to call the parameterized constructor instead of default constructor then you could change the above statement to:
ExpoFilter(2.0f / (N + 1));
"Default constructor" in this context means a constructor that takes no arguments, i.e.
ExpoFilter() {...}
You have a constructor that takes an int argument, and a constructor that takes a float argument, but no constructor that takes no arguments. So code like this:
ExpoFilter alpha_temp;
... can't compile because the compiler doesn't know how to construct the object with no argument supplied.
Btw, this line:
ExpoFilter(alpha_temp);
.... is not calling a constructor-method on your object; rather it is constructing a second (temporary/anonymous) ExpoFilter object that is created on the stack and then immediately destroyed -- probably not what you intended. (in particular, that line won't change the state of your original ExpoFilter object!). If you want to delegate to another constructor-method from within your constructor (and you are compiling with C++11 or newer) you'll need to call the other-constructor from your constructor's initializer-list instead:
ExpoFilter::ExpoFilter(int N)
: ExpoFilter(2.0f / (N + 1))
{
// ...
}

Default argument allowing constructor to call private method

I have the class
class A
{
public:
class Key
{
Key() {}
Key(Key const &) {}
};
A(Key key, int a = 5) {}
};
The constructor for Key is private, so no one should be able to construct an object A. However, with the following code:
int main() {
A a(A::Key()); // this compiles !!!
A a2(A::Key(), 5); // this doesn't
// somehow defaulting the argument causes the private constructor
// to be OK - no idea why
return 0;
}
By making use of the default argument for int a in my constructor, the compiler happily compiles my usage of A::Key() despite the fact that it is private. If I explicitly give a value for a, though, the compiler correctly recognizes that I am trying to use a private constructor and errors out. Why is this? Is there someway to force the compiler to error out for the first example as well?
See here for live example.
This is because of the most vexing parse.
A a(A::Key());
Does not create a A named a and construct it with a temporary A::Key. It creates a function a that returns an A and takes an unnamed pointer to function that returns a A::Key.
If you add a pair of parentheses to it you will get a compiler error
A a((A::Key()));
That you are trying to call a private constructor. Alternatively you can use uniformed initialization which also disambiguate it and will cause a compile error
A a(A::Key{});

Call constructor inside another constructor (no matching function to call...) c++

I've written an Array class to create 1d,2d and 3d array and it works fine for every test : example of the constructor of the array class for 2d case:
Array::Array( int xSize, int ySize )
{
xSize_ = xSize;
ySize_ = ySize;
zSize_ = 1;
vec.resize(xSize*ySize);
}
It works fine , but when i need to use this constructor inside of other constructor, i get the "no matching function error" ,
part of my code:
class StaggeredGrid
{
public:
StaggeredGrid ( int xSize1, int ySize1, real dx, real dy ) : p_ (2,2) {}
protected:
Array p_;
complete error:
No matching function for call to Array::Array()
Candidates are : Array::Array(int)
Array::Array(int, int)
Array::Array(int, int, int)
I would appreciate if anybody knows the problem
Your Array class has three constructors, taking one, two, and three ints, respectively. If StaggeringGrid has a default constructor, it will invoke Array::Array(), which doesn't exist, from what you told.
The thing is that then you declare and don't initialize in the StaggeredGrid's constructor
Array p_;
the default constructor should be called, which seems to be missing in your code.
Simple adding empty default constructor should solve a problem.
class Array
{
public:
Array(){}
// ...
};
Once you define any of the constructor in a class, the compiler does not defines implicitly default constructor for your class.
In your case you've defined parameterized constructor "Array( int xSize, int ySize )" but your are creating a class with default constructor i.e., Array p_. This invokes your default constructor which is not exactly found by your compiler.
Solution:
Introduce a default constructor in Array class

default constructor that has the option to take in a parameter?

Is it possible to have 1 constructor have the option of being a default constructor if a parameter is not passed in.
Example, instead of having 2 constructors, where 1 is the default constructor and another is a constructor that initializes numbers passed in, is it possible to only have 1 constructor that if a value is passed in, set that value to a member function, and if no value is passed in, set the member function to a number.
example:
WEIGHT.H file:
class Weight
{
public:
Weight() { size = 0; }
Weight(int a) : size(a) {}
int size;
};
MAIN.CPP file:
int main(void)
{
Weight w1;
Weight w2(100);
}
I've been working on different school projects and they all require to have different types of constructors, and i'm wondering if there is a way to only have it once so it saves time.
Thanks for the help.
Yes, a constructor parameter may have a default argument, just like other functions can. If all of the parameters of a constructor have default arguments, the constructor is also a default constructor. So, for example,
class Weight
{
public:
explicit Weight(int a = 0) : size(a) { }
int size;
};
This constructor may be called with a single argument or with no arguments; if it is called with no arguments, 0 is used as the argument for the a parameter.
Note that I've also declared this constructor explicit. If you have a constructor that may be called with a single argument, you should always declare it explicit to prevent unwanted implicit conversions from occurring unless you really want the constructor to be a converting constructor.
(If you aren't familiar yet with converting constructors or implicit conversions, that's okay; just following this rule is sufficient for most of the code you'll ever write.)
Yes its possible as suggested by James but as you know if you are not defining the Default constructor the compiler would take over the definition part if you have not provided any constructor definition.
Its not an issue as such but its a better practice to define the Default constructor for proper initialization of values.
Google C++ Style guide also recommends it.

=default in class constructors

I know that making a constructor like this:
foo()=delete;
will make it unnaccesible, but what about:
foo()=default;
? I saw this sometimes, but I dont know whatit means!
Here's how default is useful. Recall that in order to be POD ("plain old data"), a class type must have a trivial default constructor:
struct this_is_pod
{
int a;
double b;
};
struct this_is_not_pod
{
char c;
float d;
this_is_not_pod() { }
};
However, what if we would like to provide a means for initializing the class members in some non-trivial way? Just writing a non-default constructor doesn't work:
struct foo
{
int m;
void * p;
foo(double q, Bar & o) : m(magic(q), p(o.gizmo(m, q)) { }
};
Now foo is not POD, because it lacks a default constructor altogether. Adding our own default constructor, like foo() {}, still doesn't work because now the default constructor isn't trivial. C++11 comes to the rescue with default:
struct foo
{
int m;
void * p;
foo(double q, Bar & o) : m(magic(q), p(o.gizmo(m, q)) { }
foo() = default; // trivial!
};
static_assert(std::is_pod<foo>::value, "You will never see this message.");
In C++03, if you don't define any constructor, the compiler generates a default constructor for you. If you do define some other constructor, however, the compiler doesn't generate a default constructor (at all).
The =default tells the compiler to generate a default constructor even though you've explicitly defined some other constructor as well. This was added in C++11 -- there was no way to do the same in C++03 (or 98). Any constructor you define explicitly differs at least a little from what the compiler generates by default.
It tells the compile to guess a default constructor, meanign one with no arguments. This is what the compilers usually do if no "delete" is given. It is introduced in C++11 as well as the delete option.
Compiler will implicitly generate a default constructor, unless you explicitly defined any constructor yourself.
The foo() = default; simply instructs the compiler to generate the default constructor even if you defined a non-default one. It's mostly the same as foo() {} (but see Kerrek SB's answer).