-2

I am developing a new project using c++:

File A.cpp

#ifndef A_hpp
#define A_hpp

class A{

public:
    A(int at, int bt);
    ~A();
    virtual double b()=0;
    virtual double c()=0;
    virtual double g()=0;
private:
    int at;
    int bt;
};

#endif /* A_hpp */

File A.cpp

#include "A.hpp"

A::A(int at, int bt){
    this->at=at;
    this->bt=bt;
}

A::~A(){
    //no code
}

File B.hpp

#ifndef B_hpp
#define B_hpp

#include "A.hpp"
class B:public A{

public:
    B(int at, int bt, double val);
    ~B();

private:
    double *elems;
};
#endif /* B_hpp */

File B.cpp

#include "B.hpp"
#include "A.hpp"

B::B(int at, int bt, double val):A(at, bt){

    elems=new double[at*bt];

    for(int i=0;i<at*bt;i++)
        *(elems+i)=val;
}
B::~B(){
    delete []elems;
}

double A::c(){
        return *elem;
    }

double A::b(){
        return (*elem)-*(elem+1);
    }


double A::g(){
        return (*elem)*(*elem)*(*elem);
    }

I get an error, Use of undeclared identifier 'elem', when I implement these virtual function b(), c() et g() in the class B

LearnToGrow
  • 1,656
  • 6
  • 30
  • 53
  • 3
    Please copy-paste the error message, instead of trying to paraphrase it. EDIT: the lack of indentation and spacing made your code **very** hard to read. You are implementing `a`, `b`, `c` functions for your `A` class (`double A::b()`), and `A` class knows nothing about `elems`. Did you want to implement them for `B` class (`double B::b()`)? – Algirdas Preidžius Feb 10 '17 at 18:48
  • Indentation, please! – Hatted Rooster Feb 10 '17 at 18:50
  • Why you define A's member functions `b, c, g` in source of `B.cpp`? – Raindrop7 Feb 10 '17 at 18:59
  • More to the point, why do you bother defining `A`'s member functions `b, c, g` at all? You declared them as abstract. Also, you _should know_ that `A`'s member functions will not have access to members declared in `B`.... It does not matter what file you declare them in! – Disillusioned Feb 10 '17 at 19:03
  • @AlgirdasPreidžius, I edit my code. – LearnToGrow Feb 10 '17 at 19:05
  • @Raindrop7, I edit my code – LearnToGrow Feb 10 '17 at 19:05
  • @CraigYoung, I edit my code – LearnToGrow Feb 10 '17 at 19:05
  • If you write `double A::c(){ ...`, you do not implement `c` in class `B` but rather `c` in class `A`; and class `A` is not aware of `elem`, which is a member of `B`, right? – Stephan Lechner Feb 10 '17 at 19:08
  • @BetterEnglish All of these unnecessary pointers and `new`/`delete` mess. Use idiomatic c++ constructs please! – πάντα ῥεῖ Feb 10 '17 at 19:09
  • Replace the `new[]` stuff with `std::vector` and add a virtual destructor in the base class. These two things must be repaired in the code before proceeding with any further problems. Also consider making the public functions non-virtual and make them delegate to private virtual functions instead. – Christian Hackl Feb 10 '17 at 19:15
  • @BetterEnglish The way you've changed your code between edits suggests you're not copy-pasting from your local source code. Don't do that! You just create confusion when you inevitably make a hash job of it - _especially as you're very obviously not familiar with the nuances of the language. You make your own task more difficult and waste everyone's time when you don't do things properly. – Disillusioned Feb 10 '17 at 19:20
  • @CraigYoung, Sorry for the confusion but i have used the same code with some correction of typo. That 's it! – LearnToGrow Feb 10 '17 at 19:22
  • @πάνταῥεῖ, What do you mean by idiomatic c++ constructs! – LearnToGrow Feb 10 '17 at 19:23
  • @BetterEnglish You miss the point. You wouldn't have to correct typo's if you simply copy-paste. – Disillusioned Feb 10 '17 at 19:24
  • @BetterEnglish _"What do you mean by idiomatic c++ constructs!"_ Standard [container classes](http://en.cppreference.com/w/cpp/container), [smart ponters](http://en.cppreference.com/w/cpp/memory). – πάντα ῥεῖ Feb 10 '17 at 19:33

4 Answers4

0

There is a typo. Change elem to elems.

Plus,

To imlement virtual inheritace you have to add the methods in the class B header:

virtual double b();
virtual double c();
virtual double g();

And in the implementation change namespace A by B in the .cpp:

double B::c(){
        return *elems;
    }
double B::b(){
        return (*elems)-*(elems+1);
    }
double B::g(){
        return (*elems)*(*elems)*(*elems);
    }
Rama
  • 3,222
  • 2
  • 11
  • 26
0

The issue is that you are implementing the overrides for the base classes virtual functions incorrectly.

What your code is actually doing is implementing the pure virtual functions from A while trying to use the class member variables from B

Given your base class:

class A
{
public:
    A(int at, int bt);
    ~A();
    virtual double b()=0;
    virtual double c()=0;
    virtual double g()=0;
private:
    int at;
    int bt;
};

Your child class should be:

class B:public A
{
public:
    B(int at, int bt, double val);
    ~B();
    virtual double b();
    virtual double c();
    virtual double g();
private:
    double *elem;
};

With the implementation of B like so:

B::B(int at, int bt, double val):A(at, bt)
{
    elem=new double[at*bt];
    for(int i=0;i<at*bt;i++)
    {
        *(elem+i)=val;
    }
}
double B::a()
{
    return *elem;
}
B::~B()
{
    delete []elem;
}
double B::b()
{
    return (*elem)-*(elem+1);
}

double B::g()
{
    return (*elem)*(*elem)*(*elem);
}
Alex Zywicki
  • 2,263
  • 1
  • 19
  • 34
0

I think you misinterpret placing an implementation in a particular B.cpp-file as "implementing something in class B". If you write double A::c(){ ..., you do not implement c in class B but rather c in class A, regardless in which file you write this implementation. And class A is not aware of elems, which is a member of B, what explains the error message Use of undeclared identifier 'elem'.

Write double B::c(){ ... instead, and also declare double c() in the definition of class B. (The same of course for the other functions)

Stephan Lechner
  • 34,891
  • 4
  • 35
  • 58
0

elems is a member of class B which derived from class A so you cannot access the members of a child from the parent:

double A::b(){ 
    return (*elems)-*(elems+1); // elems is a member of B not A
}
Raindrop7
  • 3,889
  • 3
  • 16
  • 27