Instantiating doubly inherited object properly? - c++

I am trying to use double inheritance, to declare a more complex object, as the sum of two simpler ones. However when I try to do it as follows:
class common_cfullr
{
public:
double core;
double thr;
double thrres;
common_cfullr(double Core, double Thr, double Thrres){
core=Core;
thr=Thr;
thrres=Thrres;
};
~common_cfullr(){};
common_cfullr() :
core(0.0),
thr(0.0),
thrres(0.0)
{}
};
class common_cfull
{
public:
int nelec;
int ms2;
common_cfull (int Nelec,
int Ms2){
nelec =Nelec;
ms2 =Ms2;
};
~common_cfull(){};
common_cfull() :
nelec(0),
ms2(0){}
};
///Structure inheritance
class common :
public common_cfullr,
public common_cfull
{public:
common(){};
~common(){};
};
int main(int argc, char** argv)
{
common cmn();
cmn.nelec=0;
return 0;
}
I get an error from the compiler. How can I use doubly inheritance properly, for this purposes?
Any sugestion will be very appreciated.

(Based on Neik Kirk's comment.) Changing common cmn(); to common cmn; makes your code compile without an error.
When compiling with clang++, the note emitted by the compiler also tells you this:
t.cc:48:13: warning: empty parentheses interpreted as a function declaration
[-Wvexing-parse]
common cmn();
^~
t.cc:48:13: note: remove parentheses to declare a variable
common cmn();
^~

Related

Instance of C++ template class as a member of another template class

Let's say I have following templated C++ class
#include <cstdint>
template <uint32_t NO_POINTS>
class A
{
public:
struct Point
{
float x;
float y;
};
A(const Point (&points)[NO_POINTS])
{
for (uint32_t point = 0; point < NO_POINTS; point++) {
table[point] = points[point];
}
}
private:
Point table[NO_POINTS];
};
and I would like to use an instance of this class as a private member of the following class:
#include "A.h"
template <uint32_t NO_LUT_POINTS>
class B
{
public:
B(A<NO_LUT_POINTS>::Point (&table)[NO_LUT_POINTS]) : lut(table){}
private:
A<NO_LUT_POINTS> lut;
};
#include "B.h"
int main(int argc, char** argv) {
B<4> foo({{1326.0, 25.0}, {1601.0, 30.0}, {1922.0, 35.0}, {2293.0, 40.0}});
return 0;
}
I have attempted to compile this code but the compiler reports following error
A<NO_LUT_POINTS>::Point is not a type. I don't understand what the reason for this error is. Can anybody explain to me why the compiler reports this error?
This is a common mistake with types nested in template classes. You need to add typename to tell the compiler that Point is a type.
...
public:
B(typename A<NO_LUT_POINTS>::Point const (&table)[NO_LUT_POINTS]) : lut(table){}
...
Beyond solving your problem, however, please notice that Point doesn't depend on the template parameters of A, so you should not nest it in that class. This would remove the necessity for adding typename.

pass pointer to template member of template class

I'm searching for a way to have a function of my template class which accepts as a parameter a member of the template (it could be either one of its arguments or functions).
model.h
template <class T>
class Model
{
public:
Model(){}
void relate(int T::*, int ){}
};
main.cpp
#include "model.h"
class element
{
public:
element();
char getA(){return this->a;}
int getB(){return this->b;}
char a;
int b;
};
int main(int argc, char *argv[]){
Model<element *> model;
return 0;
}
it gives the creating pointer to member of non-class type ‘element*’ error.
I agree with that since pointer must point to some defined type memory area.
My final goal is to tell my class that I want to relate a specific member of its template with some number which later will be used to order different members in a list which later will be displayed.
This wont be used with types such as Model<int> but only with other classes.
Your instantiate a Model<element*> hence this:
void relate(int T::*, int ){}
is (just hypotheically):
void relate(int element*::*, int) {}
Its a "pointer to member of a pointer type". If you instantiate a Model<element> your code works fine. Alternatively you can use std::remove_pointer<T>.
EDIT:
suddenly I'm figuring out... I used a poiter as a template...
but the game changes now...
int main(int argc, char *argv[]){
Model<element> model;
element e;
model.relate(&element::getA(), 0); // <- call to non static-member error
model.relate(&element::getB(), 0); // <- call to non static-member error
model.relate(&element::a, 0); // <- type mismatch error
model.relate(&element::b, 0); // <- no error
}

Member is inaccessible

class Example{
public:
friend void Clone::f(Example);
Example(){
x = 10;
}
private:
int x;
};
class Clone{
public:
void f(Example ex){
std::cout << ex.x;
}
};
When I write f as a normal function, the program compiles successful. However, when I write f as a class member, this error occurs.
Screenshot:
The error you're seeing is not a root-cause compilation error. It is an artifact of a different problem. You're friending to a member function of a class the compiler has no earthly clue even exists yet,much less exists with that specific member.
A friend declaration of a non-member function has the advantage where it also acts as a prototype declaration. Such is not the case for a member function. The compiler must know that (a) the class exists, and (b) the member exists.
Compiling your original code (I use clang++ v3.6), the following errors are actually reported:
main.cpp:6:17: Use of undeclared identifier 'Clone'
main.cpp:17:25: 'x' is a private member of 'Example'
The former is a direct cause of the latter. But doing this instead:
#include <iostream>
#include <string>
class Example;
class Clone
{
public:
void f(Example);
};
class Example
{
public:
friend void Clone::f(Example);
Example()
{
x = 10;
}
private:
int x;
};
void Clone::f(Example ex)
{
std::cout << ex.x;
};
int main()
{
Clone c;
Example e;
c.f(e);
}
Output
10
This does the following:
Forward declares Example
Declares Clone, but does not implement Clone::f (yet)
Declares Example, thereby making x known to the compiler.
Friends Clone::f to Example
Implements Clone::f
At each stage we provide what the compiler needs to continue on.
Best of luck.

error in declaring the class type variable

#include <iostream>
using namespace std;
class A{
private:
int x;
public:
A(){
x=0;
}
A(int i)
{
x=i;
}
int Get_x(){
return x;
}
};
class B{
private:
A objA(1);
public:
objA.Get_x();
};
This is my code and it has two classes i.e A and B ..First class runs fine but in class B ..compiler gives the syntax error in the declaration of objB.....But as far as i know it should be correct ...so plz help ....thanks
This initialization is invalid for a data member:
A objA(1);
You need
A objA{1};
or
A objA = A(1);
Besides that, this kind of statement can only happen inside of a function:
objA.Get_x();
The compiler is trying to interpret A objA(1) as a function declaration, which is wrong. You may declare objA as A objA = A(1); (please note that thi is a C++11 feature, you may need to enable it before).
Also, I don't really know what objA.Get_x() should do, but this is also wrong, you can't just access a member outside of a function. Probably, you meant this:
int Get_x() {
return objA.Get_x();
}

Inheritance and static variables

Here is my code -
#include <iostream>
#include <conio.h>
using namespace std;
class Base
{
public:
int a;
};
//int Base::a = 5;
class Derived : public Base
{
public:
int static a;
};
int main()
{
Derived d;
cout<<d.a;
getch();
return 0;
}
I get a linker error here. But when I do it the other way round -
class Base
{
public:
int static a;
};
int Base::a = 5;
class Derived : public Base
{
public:
int a;
};
I get no error. Can someone please explain what is happening here.
All static members have to be explicitly defined/initialized outside the class.
In the second example you do this correctly (int Base::a=5), but in the first example you don't do this for Derived::a, adding the following line to the first example should solve it:
int Derived::a = 5;
You need to actually define static members. The same way as you do
int Base::a = 5
in the second case you should have done
int Derived::a = 5;
in the first case.
There are two questions here.
The first is why do you get the linker error in the first example?
Well, you get a linker error in the first example because you have not defined/initialized the static member of class B.
The second question is why does the compiler not complain of multiple declarations?
The compiler does not complain of multiple declarations because as far as it is concerned, the two variables are in different scopes and their mangled names will be different anyway. This has got nothing to do with one of the variables being static. In fact, static members are not even inherited. SO, the following code snippet without static variables is also correct:
class B {
public:
int a;
};
class C: public B {
public:
int a;
};