I'm a little new with OOP and I have a small problem with a constructor inside of a derived class.
I have the following code:
class Functionar{
protected:
char nume[20];
int cnp;
public:
Functionar(char *n,int c){strcpy(nume,n); cnp=c;}
virtual void Afisare();
};
void Functionar::Afisare()
{
cout<<"Nume: "<<nume<<endl<<"CNP: "<<cnp<<endl;
}
class Permanent:public Functionar{
protected:
int salariu;
int nrorelucrate;
public:
//Permanent(char *n,int c,int s,int nr): Functionar(char *n,int c),salariu(s),nrorelucrate(nr){}
Permanent(char *n,int c,int s,int nr)
{
Functionar(char *n,int c);
salariu=s;
nrorelucrate=nr;
}
//void Afisare();
};
main()
{
Functionar Claudiu("Claudiu",495);
Claudiu.Afisare();
}
Sorry for the variable and function names. They might look a little strange. The idea is that I want to create a constructor in the derived class using the base constructor for nume and cnp.
I have a couple of errors:
In constructor 'Permanent::Permanent(char*, int, int, int)':
[Error] no matching function for call to 'Functionar::Functionar()'
[Note] candidates are:
[Note] Functionar::Functionar(char*, int)
[Note] candidate expects 2 arguments, 0 provided
[Note] Functionar::Functionar(const Functionar&)
[Note] candidate expects 1 argument, 0 provided
[Error] expected primary-expression before '(' token
[Error] expected primary-expression before 'char'
[Error] expected primary-expression before 'int'
C:\Users\Stefan\Desktop\Probleme Culegere POO\problema12.cpp In function 'int main()':
[Warning] deprecated conversion from string constant to 'char*' [-Wwrite-strings]
I don't understand why there is no matching for 'Functionar::Functionar()'. Thank you.
Use
Permanent(char *n,int c,int s,int nr) :
Functionar(n,c)
//your other variables go here
{
}
Without the initializer list, a default constructor is required because the class attempts to default-initialize the its base.
Even if you did have a default constructor for Functionar, your version would just create a temporary object that would get destroyed after the ; and not initialize the base as you would expect.
You should use a constructor's initializer list to call constructor of the base class(especially for ctors with arguments), such as:
Permanent(char *n, int c, int s, int nr) : Functionar(n, c), salariu(s), nrorelucrate(nr) {}
Related
environment: C++11/14 and MacOS Clion
First, I know it is better to construct a unique_ptr with nullptr rather than with int: 0, but I just wonder what causes the following two compilation results:
// compile just fine
class MyClass {};
void MyFunc(unique_ptr<MyClass>) {
}
int main() {
MyFunc(0);
return 0;
}
// compile error
class MyClass {};
void MyFunc(unique_ptr<MyClass>) {
}
int main() {
MyFunc(int(0));
return 0;
}
the latter one with error:
note: candidate function not viable: no known conversion from 'int' to 'unique_ptr' for 1st argument
After examining unique_ptr's constructor, I find the following a canditate:
constexpr unique_ptr( nullptr_t ) noexcept;
So I try further:
// good
int main() {
nullptr_t mynullptr(0);
return 0;
}
on the other hand:
// error
int main() {
nullptr_t mynullptr(int(0));
return 0;
}
with message:
error: cannot initialize a variable of type 'std::nullptr_t' (aka 'nullptr_t') with an rvalue of type 'int'
nullptr_t mynullptr(int(0));
So is it because the initialization of nullptr that leads to the compile error?
Credit on the comment of M.M:
literal 0 may be converted to nullptr ; other integer expressions may not (even if they are constant and have value zero)
I'm trying to set one of the elements of an array to be a different object. But, the compiler is deleting the = operator. Why is it doing that here, exactly? And how can I work around it?
Example code:
struct IntContainer
{
IntContainer(const int value) :
value(value)
{
}
IntContainer() :
IntContainer(0)
{
}
const int value;
};
int main(int argc, char** argv)
{
IntContainer intContainers[3];
IntContainer newIntContainer(420);
intContainers[0] = newIntContainer; // <-- Causes compiler error
return 0;
}
The compiler error I'm getting when compiling this snippet is:
main.cpp: In function 'int main(int, char**)':
main.cpp:23:24: error: use of deleted function 'IntContainer& IntContainer::operator=(const IntContainer&)'
intContainers[0] = newIntContainer; // <-- Causes compiler error:
^~~~~~~~~~~~~~~
main.cpp:2:8: note: 'IntContainer& IntContainer::operator=(const IntContainer&)' is implicitly deleted because the default definition would be ill-formed:
struct IntContainer
^~~~~~~~~~~~
main.cpp:2:8: error: non-static const member 'const int IntContainer::value', can't use default assignment operator
The compiler generally gives you operator= and the copy constructor for free, but when a class contains a const member, it makes no sense to generate operator= because you can't perform an assignment to the const member.
You could write your own, but you still wouldn't be able to assign values to the const member.
g++ compiler complains about:
error: no matching function for call to ‘AddressSpace::resolve(ClassOne&, ClassTwo*&, ClassThree&) const’
note: candidates are: bool AddressSpace::resolve(ClassOne&, ClassTwo*, ClassThreer) <near match>
The code causing this error is
void Class::handler(ClassOne& objOne, ClassTwo& objTwo,
ClassThreer objThree) {
obj.getAddressSpaceObj().resolve(objOne, objTwo.pointer, objThree);
}
I digged into the code and found this error is caused by the reference type returned by getOtherObj() . I make it to return a const reference to the AddressSpace object in the class definition, see
const AddressSpace &getAddressSpaceObj(){
return addressSpace;
}
After I change this definition to return a normal reference,
AddressSpace &getAddressSpaceObj(){
return addressSpace;
}
the compiler doesn't complain about it any more. I wonder why this error is declared as parameter mismatching error? Why compiler didn't copy content as the parameters of function call but passed them as references?
If resolve does not have a const specifier then you can not call it on a const reference, so that would be consistent with changing it to be being non-const and having it now work. Here is a really trivial example:
#include <iostream>
class A
{
public:
void someFuncA() {};
void someFuncB() const {} ;
} ;
int main()
{
A
a1 ;
const A &aRef = a1 ;
a1.someFuncA() ;
// Below won't work because aRef is a const & but someFuncA() not const
//aRef.someFuncA() ;
// Below will work since someFuncB() is const
aRef.someFuncB() ;
}
Just for completeness sake, if you uncomment aRef.someFuncA() then the error you will receive will be similar to this:
19:19: error: no matching function for call to 'A::someFuncA() const'
19:19: note: candidate is:
6:12: note: void A::someFuncA() <near match>
please have a look at this program and the error it is generating:
#include <iostream>
using namespace std;
class A
{
public:
virtual void f(){}
int i;
};
class B : public A
{
public:
B(int i_){i = i_;} //needed
B(){} //needed
void f(){}
};
int main()
{
//these two lines are fixed(needed)
B b;
A & a = b;
//Assignment 1 works
B b1(2);
b = b1;
//But Assignment 2 doesn't works
B b2();
b = b2; // <-- error
}
upon compilation, I get the following error:
$ g++ inher2.cpp
inher2.cpp: In function ‘int main()’:
inher2.cpp:32:10: error: invalid user-defined conversion from ‘B()’ to ‘const B&’ [-fpermissive]
inher2.cpp:14:6: note: candidate is: B::B(int) <near match>
inher2.cpp:14:6: note: no known conversion for argument 1 from ‘B()’ to ‘int’
inher2.cpp:32:10: error: invalid conversion from ‘B (*)()’ to ‘int’ [-fpermissive]
inher2.cpp:14:6: error: initializing argument 1 of ‘B::B(int)’ [-fpermissive]
Can you help me find the problem? thank you
Your "B b2();" is the 'vexing parse' problem of C++ (see here - the 'most vexing parse' takes the ambiguous syntax further).
It looks to the C++ compiler that you are declaring a function (a pre-declaration).
Check it out:
int foo(); //A function named 'foo' that takes zero parameters and returns an int.
B b2(); //A function named 'b2' that takes zero parameters and returns a 'B'.
When you later do:
b = b2;
It looks like you are trying to assign a function (b2) to a variable (b).
To call a constructor with zero parameters, call it without the parentheses and you'll be fine:
B b2;
For more information, see:
Understanding 'most vexing parse' - why allow ambiguous syntax?
Most vexing parse: why doesn't A a(()); work?
B b2();
It is a function declaration, not a variable declaration!
The function name is b2 which takes no argument, and returns object of type B.
Search for vexing parse in C++.
class Sample
{
public:
Sample();
Sample(int i);
Sample(Sample& s);
~Sample();
};
Sample::Sample()
{
cout<<"Default constructor called\n";
}
Sample::Sample(int i)
{
cout<<"1-argument constructor called\n";
}
Sample::Sample(Sample& s)
{
cout<<"Copy constructor called\n";
}
Sample::~Sample()
{
cout<<"Destructor called\n";
}
void Fun(Sample s)
{
}
int main()
{
Sample s1;
Fun(5);
return 0;
}
I expected an implicit conversion of 5.
But, When I compile the above code, I get following error:
main.cpp:7:8: error: no matching function for call to ‘Sample::Sample(Sample)’
main.cpp:7:8: note: candidates are:
Sample.h:10:3: note: Sample::Sample(Sample&)
Sample.h:10:3: note: no known conversion for argument 1 from ‘Sample’ to ‘Sample&’
Sample.h:9:3: note: Sample::Sample(int)
Sample.h:9:3: note: no known conversion for argument 1 from ‘Sample’ to ‘int’
Sample.h:8:3: note: Sample::Sample()
Sample.h:8:3: note: candidate expects 0 arguments, 1 provided
Helper.h:6:13: error: initializing argument 1 of ‘void Fun(Sample)’
What is the problem? When i remove the copy constructor, the above code compiles successfully.
Thanks in advance.
Temporaries cannot bind to non-const references. Your copy constructor should be:
Sample::Sample(const Sample&)
Removing it tells the compiler to generate a trivial one, which will have the above signature.