How to deal with base class and pointer variable in argument - c++

I am trying to deal with abstract class argument, trying to figure out what to do, after running this code below getting the error : "In function 'int main()': 67:12: error: expected primary-expression before ')' token"
#include <iostream>
#include <string>
using namespace std;
class base1 {
protected:
int i;
public:
base1(int x) {
i=x;
cout << "Constructing base1\n";
}
virtual ~base1() {
cout << "Destructing base1\n";
}
};
class derived: public base1 {
int j;
public:
derived(int x, int y): base1(y){
j=x;
cout << "Constructing derived\n";
}
~derived() {
cout << "Destructing derived\n";
}
void show() {
cout << i << " " << j << " " << "\n";
}
};
class Isolver
{
public :
Isolver(){};
virtual ~ Isolver(){};
virtual void x(base1* pboard)=0;
};
class vr:public Isolver
{
void x(base1* pboard)
{
cout << "My virtual fun and base constructor are not working\n"<<endl;
};
};
int main()
{
vr obj;
obj. x(10, );
derived ob(3,4);
ob.show();
return 0;
}

Like Paul Rooney pointed out the comma inside obj.x(10,) should not be there because with the comma the compiler is expecting two arguments and since there is nothing after the comma it shows an error.
This is what you need to do inside main:
vr obj;
base1 b(1);
obj. x(&b);
or this:
vr obj;
derived ob(3,4);
obj. x(&ob);
ob.show();
and inside class vr
class vr:public Isolver
{
public:
void x(base1* pboard)
{
cout << "My virtual fun and base constructor are not working\n"<<endl;
}
};

Related

Overloading a virtual function

I am trying to overload a virtual function, like this:
#include<iostream>
#include<string>
using std::cout;
using std::endl;
using std::string;
class Base{
public:
virtual void show(int x){
cout << "Showing int as Base: " << x << endl;
}
};
class Derived : public Base{
public:
using Base::show;
virtual void show(string s){
cout << "Showing string as Derived: " << s << endl;
}
};
int main(){
Derived x;
Base& ref = x;
ref.show(3);
ref.show(string("hi")/*in case the compiler refuses to implicitly convert const char* to std::string*/);
}
However, GCC complains error: cannot convert 'std::string' {aka 'std::__cxx11::basic_string<char>'} to 'int', and says note: initializing argument 1 of 'virtual void Base::show(int)'
It seems like gcc just ignored the Derived's overload of show.
I suspect that overloading together with polymorphism is just a BIT too much to handle for the compiler, since that would require storing the type information in the vtable as well, which MAY be not possible.
But then, what should I do to mimic this behaviour?
This worked:
#include<iostream>
#include<string>
#include<any>
using std::cout;
using std::endl;
using std::string;
using std::any;
using std::any_cast;
class Base{
public:
virtual void show(int x){
cout << "Showing int as Base: " << x << endl;
}
virtual void show(any x) = 0;
};
class Derived : public Base{
public:
using Base::show;
virtual void show(any s) override{
if(s.type() != typeid(std::string)){
if(s.type() != typeid(int)){
throw "SOME_ERROR_INDICATING_INVALID_FUNCTION_CALL";
}
Base::show(any_cast<int>(s));
return;
}
cout << "Showing string as Derived: " << any_cast<string>(s) << endl;
}
};
int main(){
Derived x;
Base& ref = x;
ref.show(3);
ref.show(string("hi")/*invokes show(any) override */);
}
but it seems really stupid. Is there any other workaround?
EDIT: adding virtual void show(string x)=0; to base is NOT desireable. This is just a MRE, and in the real program I have lots of derived classes, and I don't want to add a pure virtual function in Base for each of those customizations.
The problem is that you're calling show through a reference to a base object while passing a std::string as an argument but the base class doesn't have any such method so this call can't succeed.
To solve this you can add a declaration for virtual void show(string s) =0; inside the base class.
class Base{
public:
virtual void show(int x){
cout << "Showing int as Base: " << x << endl;
}
//added this declaration for making it pure virtual
virtual void show(string s)=0;
};

C++ polymorphism, about announcing a basis class reference to a derived class

#include <iostream>
using namespace std;
class A {
private:
int nVal;
public:
void Fun()
{
cout << "A::Fun" << endl;
}
void Do()
{
cout << "A::Do" << endl;
}
};
class B :public A {
public:
virtual void Do()
{
cout << "B::Do" << endl;
}
};
class C :public B {
public:
void Do()
{
cout << "C::Do" << endl;
}
void Fun()
{
cout << "C::Fun" << endl;
}
};
void Call(B& p)
{
p.Fun(); p.Do();
}
int main() {
C c; Call(c);
return 0;
}
In the above code, the output is
A::Fun
C::Do
But I cannot understand. in the function call(B& p), the reference p should refer to c from C class, so why the output is not
C::Fun
C::Do
When announcing a a basis class reference to a derived class, is the different basis class making any sense?
The problem is that A::Fun is not marked as virtual, therefore it doesn't find C::Fun at run-time. You should mark it as such:
class A {
private:
int nVal;
public:
virtual void Fun()
{
cout << "A::Fun" << endl;
}
// ...
wandbox example
This is a great example of an error that could be caught at compile-time thanks to the override specifier:
class C :public B {
public:
void Do() override
{
cout << "C::Do" << endl;
}
void Fun() override
{
cout << "C::Fun" << endl;
}
};
Would print:
error: 'void C::Fun()' marked 'override', but does not override
void Fun() override
^~~
wandbox example

C++ dynamic_cast runtime-error

I have written a small application using dynamic_cast to determine whether it is form the base class or the child class and invokes the function according to it. But when ever child class
runs, it displays it function twice and no sure why it does that.
#include <iostream>
using namespace std;
class Base{
public:
virtual void setting(){
cout << "Hello, I am a function from the base class" << endl;
}
virtual void say(){
cout << "Base class says hi" << endl;
}
};
class Child:public Base{
public:
void setting(){
cout << "Hello, I am a function from the child class" << endl;
}
void say(){
cout << "Child class says hi" << endl;
}
};
void Ready(Base* input){
Base* bp = dynamic_cast<Base*>(input);
if(bp){
bp->setting();
bp->say();
}
Child* cp = dynamic_cast<Child*>(input);
if(cp){
cp->say();
cp->setting();
}
}
int main(){
Base b;
Child c;
Ready(&b);
cout << endl;
Ready(&c); //runs twice for some reason
system("pause");
return 0;
}
When you pass a pointer to Child to the Ready function, both dynamic_casts succeed. Child is both a Base and a Child.
Here's a simplified example:
struct Foo
{
virtual ~Foo() {}
};
struct Bar : Foo {};
#include <iostream>
int main()
{
Bar b;
std::cout << dynamic_cast<Foo*>(&b) << std::endl;
std::cout << dynamic_cast<Bar*>(&b) << std::endl;
}

Virtual functions and Private members with Public Inheritance in C++

When a class inherits another publicly, then shouldn't all virtual functions get rewritten?
Consider the code --
class A {
private:
vector<int> v;
public
virtual int something() {
cout << "A" << endl;
return v.size();
}
}
class B : public A {
private:
priority_queue<int> v;
public
int something() {
cout << "B" << endl;
return v.size();
}
}
Now, when I call the function something() on an object b of class B by executing the statement b.something(), I get the output A. Why is this?
Corrected the errors (see http://codepad.org/ssivYhWb)
i.e.
#include <iostream.h>
class A {
private:
vector<int> v;
public:
virtual int something() {
cout << "A" << endl;
return v.size();
}
};
class B : public A {
private:
priority_queue<int> v;
public:
int something() {
cout << "B" << endl;
return v.size();
}
};
int main() {
B b;
b.something();
return 0;
}
It returns B - as expected

Implicit Conversion

My program was:-
#include < iostream.h>
#include < conio.h>
struct base
{
protected:
void get()
{
cin>>a>>b;
}
public:
base(int i=0, int j=0);
void put()
{
cout << a << '\t' << b << "\tput 1";
}
int a,b,c;
~base()
{
cout << "base destroyed";
}
};
class deri : protected base
{
int c,d;
char w;
int ans;
public:
deri(int r=7, int s=0)
: base(r,s)
{
c=r;
d=s;
cout << "\nDerived invoked\n";
}
void put()
{
cout << c << '\t' << d << '\t' << a << '\t' << b;
}
};
class d2 : protected deri
{
public:
d2() {}
void start();
void add()
{
get(); // ERROR HERE: Implicit conversion of 'd2 *' to 'base *' not allowed
}
~d2(){}
};
void d2::start()
{
put();
}
base::base(int i, int j)
{
a=i;
b=j;
cout << "\nbase invoked\n";
cout << "Enter a,b: ";
get();
}
void main()
{
clrscr();
getch();
}
CAN anyone explain what the error msg means?
You are probably using an old compiler as you're including <iostream.h> instead of the new standard <iostream> and you aren't using namespace std.
After fixing this, adding the line using namespace std; on top and commenting out clrscr() your code compiles fine on MSVC8.
Do you have a clear reason to use protected derviation ? If not, I'd suggest using public derviation instead. protected derviation is something really quite complicated and uncommon.
When you derive a base class using protected or private then your derived class is not treated as base class and compiler will not perform implicit type conversion in that case.
Derived class in not base class in case of private or protected inheritance.
whereas in case of public inheritance every derived class is a base class .
Try out explicit type casting in the function or make inheritance public.