I am getting an error "class Derived has no member named 'getX'" When I try to compile code like this:
class Base
{
public:
int getX() {return x};
protected:
int x;
};
class Derived : public Base
{
public:
void myFunction(){int y = getX()};
};
I contrived this example to help clarify, because I got a lot of errors like this when my derived class tries to use methods from the parent class that it should have inherited. I have tried using the 'this' keyword before the method invocation, but that did not work either. Thanks for any help.
Correcting your code
class Base
{
public:
int getX() {return x; }
protected:
int x;
};
class Derived : public Base
{
public:
int myFunction(){int y = getX(); return y; }
};
compiles for me with
g++ -c -o /dev/null -Wall derive.c
.
Kindly read the errors.Here there is no issue in calling base class function. The compilation errors are related to syntax mistake.
Refer the compiling code in below.
class Base
{
protected:
int x;
public:
int getX() {return x;};
};
class Derived : public Base
{
public:
void myFunction(){int y = getX();};
};
You should use better coding style, that may solve an issue.
Your code:
int getX() {return x};
It actually is:
int getX()
{
return x
};
As you see ; is put in wrong place. And have to be:
int getX()
{
return x;
}
The same problem is in void myFunction(){int y = getX()}; line.
After hours of trying to get the code to compile, I just gave up and copied all of the parent's methods and members into the children classes. Thanks for the answers anyways.
Related
I have a base product class with a few private members and a public getter that derived classes inherit. I would like to disqualify instantiation, since the class is intended for use with an abstract factory. I thought protected con/destructors might work, however, this breaks my smart pointers. Friending seems like a useful disaster. Is there a well-known solution to this, or should I resign myself to the fact that any client who has the factory injected must also know enough to instantiate the base product?
class Product
{
private:
char type_name;
char size_name;
public:
Product(char, char);
virtual ~Product() {}
void Print();
};
Use a token key.
private:
Product(char, char);
struct key_t{explicit key_t(int){}};
static key_t key(){return key_t(0);}
public:
Product(key_t, char a, char b):Product(a,b){}
static std::shared_ptr<Product> make_shared(char a, char b){ return std::make_shared<Product>(key(),a,b); }
anyone with a Product::key_t can construct a Product without being a friend. And without the key, you cannot.
This lets Product pass creation-rights as a value.
Smart pointers with configurable destroy code can use similar techniques. But I'd just make the destructor public.
Your static member function, or friend function, which is the factory should have no problem with calling protected constructors and returning a smart pointer. Generally plan to return a std::unique_ptr<BaseClass> which can be converted into a std::shared_ptr if the caller wants that instead.
Make the virtual destructor public.
Update: Don't bother making the factory a friend. You only need to prevent the construction of the base and intermediate classes. Make them effectively hidden and private by hiding the implementation classes in their own source file. Or an anonymous namespace I suppose.
Here have some code of how I would do it:
#include <iostream>
#include <memory>
#include <string>
// ITest is the only class any other code file should ever see.
class ITest {
protected:
ITest() = default;
public:
virtual ~ITest() = 0;
virtual int getX() const = 0;
virtual int getY() const = 0;
};
// Destructors must always have an implementation even if they are pure virtual.
ITest::~ITest() {}
std::ostream &operator<<(std::ostream &os, const ITest &x) {
return os << '[' << x.getX() << ',' << x.getY() << ']';
}
// Declaration of constructTest factory function.
// Its definition should be hidden in a cpp file.
std::unique_ptr<ITest> constructTest(int x);
// The main function does not need to know anything except the ITest interface
// class and the constructTest function declaration.
int main(int argc, char *argv[]) {
int val = 0;
if (argc > 1)
val = std::stoi(argv[1]);
auto p = constructTest(val);
std::cout << *p << std::endl;
}
// These classes should be defined in a private header file or in a cpp file.
// Should not be visible to any other code. It has no business knowing.
// Hiding all of this implementation is sort of the point of abstract interface
// classes and factory function declarations.
class TestBase : public ITest {
private:
int x = 0;
int y = 0;
protected:
TestBase(int x = 0, int y = 0) : x(x), y(y){};
public:
int getX() const override { return x; }
int getY() const override { return y; }
};
class TestA final : public TestBase {
public:
TestA() = default;
};
class TestB final : public TestBase {
public:
TestB(int x, int y) : TestBase(x, y) {}
int getX() const override { return -TestBase::getX(); }
};
std::unique_ptr<ITest> constructTest(int x) {
// make_unique is c++14.
// For C++11 use std::unique_ptr<ITest>(new TestB(x, x)
if (x) {
return std::make_unique<TestB>(x, x);
// return std::unique_ptr<ITest>(new TestB(x, x));
}
return std::make_unique<TestA>();
}
The answer was to make the destructor a pure virtual AND to implement it with an empty body. That empty implementation is where I got tripped up. Print() doesn't need to be static.
Product.hpp
#include <memory>
class Product {
public:
virtual ~Product() = 0;
void Print();
protected:
char type_name{};
char size_name{};
private:
};
Product.cpp
#include "Product.hpp"
Product::~Product() {}
void Product::Print() {
//Print p
}
I am working on a class hierarchy where I have a base class containing a value which needs to be shared with all other derived classes in my code. I currently have this working by using a static double within a base class with pure virtual functions to set the value:
class base {
public:
static double shared_value;
virtual void set_value(double v) = 0;
virtual double get_value() = 0;
};
class derived1 : public base {
public:
void set_value(double v){ shared_value = v; }
double get_value() { return shared_value; }
};
class derived2 : public base {
public:
void set_value(double v){ shared_value = v; }
double get_value() { return shared_value; }
};
etc...
The problem comes when I use header files with my code. I know I can't define a static member variable more than once, and using the headers is giving me multiple initialization errors.
I am not sure how else I can set and view this variable from any of the classes, any help will be hugely appreciated.
You will need to define shared_value in a source file like so:
double base::shared_value = 0;
Now any child class can access that value including editing it.
I have something like this :
class X
{
method(){...};
void f()=0;
};
class my_X;
class my_Y;
class my_X: public X
{
public:
his_Y* opp;
void f()={...};
};
class his_X: public X
{
public:
my_X* opp;
void f()={...};
};
Now when I want to take profit of polymorphism and use my member opp while calling X::method() g++ says that opp was not declared. Since X is abstract, I thought the compiler would understand that method can only be called from a my_X or his_X in which opp is declared.
One trick I found would be to add a member X* opp to my class X that would subsequently be hidden by my subclasses definitions of opp.
Is this the right solution ? If not is there a solution ? Or does this issue come from a bad class design ?
One of possible solutions
class X
{
method(){... getOpp(); ...};
virtual void f()=0;
virtual X* getOpp() = 0;
};
class my_X;
class my_Y;
class my_X: public X
{
public:
his_Y* opp;
void f()={...};
X* getOpp() override { return opp; }
};
class his_X: public X
{
public:
my_X* opp;
void f()={...};
X* getOpp() override { return opp; }
};
Since X is abstract, I thought the compiler would understand that method can only be called from a my_X or his_X in which opp is declared.
No, it can't understand that. While compiling the class X, it knows nothing about derived classes.
I am trying to deal with friend class for the first time. I wrote the code below:
class Kind{
private:
friend class Type;
int x;
public:
Kind(){ x=0; }
void setX(int X) { x =X; }
int getX() { return x; }
};
class Type: public Kind {
public:
friend class Kind;
Type(){ }
Kind root;
root.x=3;
};
The compiler tells me that I can not do root.x=3;, What is the problem??
The problem is your trying to execute a statement in a place where the compiler is expecting member declarations. Try putting it into a method
class Type : public Kind {
...
void Example() {
Kind root;
root.x = 3;
}
};
You cannot do the assignment as part of the class declaration. Do it in a member function instead.
I'm writing a C++ code which should populate a screen (and it's behaviour) based on a function from the object pointer was initiated with. Let's better show it on a code:
class A:parentClass {
public:
int X () {return 5;}
}
class B:parentClass {
public:
int X () {return 3;}
}
class C:parentClass {
public:
int X () {return 1;}
}
main {
parentClass *p;
p = new A;
printf("%d\n,p.x); //to return 5
delete p;
p = new B;
printf("%d\n,p.x); //to return 3
}
I'm getting something like this on compilation:
‘class parrentClass’ has no member named ‘x’
I know that this is wrong, as parrentClass simply doesn't have that member, but I don't have an idea how to solve this. I tried to go through templates, but I'm not getting anywhere.
I also tried to replace "parentClass *p;" with "int *p;", but then I'm getting:
cannot convert ‘CardsFrame*’ to ‘int*’
Thanks for your suggestions in advance,
Jan
You need to declare the X() method virtual on the parent class for this to work:
class ParentClass
{
public:
virtual int X();
};
To be clear: the following is a complete working example (compiled with gcc):
#include <iostream>
class ParentClass {
public:
virtual int x() = 0;
};
class A : public ParentClass {
public:
int x() { return 5; }
};
class B : public ParentClass {
public:
int x() { return 3; }
};
class C : public ParentClass {
public:
int x() { return 1; }
};
int main() {
ParentClass *p;
p = new A;
std::cout << p->x() << std::endl; // prints 5
delete p;
p = new B;
std::cout << p->x() << std::endl; // prints 3
delete p;
}
You really need to get your basics right as your syntax is all wrong. You need to use p->X() to call the function. And to answer the actual question make X() virtual in the base class.
printf("%d\n,p.x); //to return 5
should be:
printf("%d\n,p->X()); //to return 5
Also, X() should be virtual in the Base class.