Function order not clear in C++? [closed] - c++

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I am executing the below program in C++, but does not compile. Please help to find the issue
#include<iostream>
class A;
void showA(A& x) {
// Since showA() is a friend, it can access
// private members of A
std::cout << "A::a=" << x.a;
}
class A
{
int a;
public:
A() {a = 0;}
friend void showA(A& x); // global friend function
};
int main()
{
A a;
showA(a);
return 0;
}
It gives me below compilation error:
In function 'void showA(A&)':
7:27: error: invalid use of incomplete type 'class A'
:cout << "A::a=" << x.a;
^
3:7: note: forward declaration of 'class A'
class A;
^

class A;
void showA(A& x) {
// Since showA() is a friend, it can access
// private members of A
std::cout << "A::a=" << x.a;
}
We don't know that A will be a friend. We don't even know that A will have a member. You can not access members of an incomplete type. Trying to do so is invalid use of incomplete type.
Solution: Make the type complete (i.e. define the class) before accessing members.

Related

Why c++ template class's needs named qualifier to visit father template class's function? [duplicate]

This question already has answers here:
Why doesn't a derived template class have access to a base template class' identifiers?
(4 answers)
Why do I have to access template base class members through the this pointer?
(3 answers)
In a templated derived class, why do I need to qualify base class member names with "this->" inside a member function?
(2 answers)
Derived template-class access to base-class member-data
(3 answers)
Closed 4 months ago.
I'm trying to write a class that inherites std::vector, and holds my own data objects, like below:
#include<iostream>
#include<vector>
using namespace std;
template <class T>
class Data {
T data;
public:
void print() { cout << data << endl; }
};
template<class T>
class Container : public std::vector<Data<T>>
{
public:
void f() {
cout << data() << endl;
}
};
int main() {
Container<int> si;
si.push_back(Data<int>());
return 0;
}
It doesn't compile, gcc says:
<source>: In member function 'void Container<T>::f()':
<source>:17:21: error: no matching function for call to 'data()'
17 | cout << data() << endl;
| ~~~~^~
In file included from /opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/string:52,
from /opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/bits/locale_classes.h:40,
from /opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/bits/ios_base.h:41,
from /opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/ios:42,
from /opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/ostream:38,
from /opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/iostream:39,
from <source>:1:
/opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/bits/range_access.h:311:5: note: candidate: 'template<class _Container> constexpr decltype (__cont.data()) std::data(_Container&)'
311 | data(_Container& __cont) noexcept(noexcept(__cont.data()))
| ^~~~
I fixed it as below:
template<class T>
class Container : public std::vector<Data<T>>
{
using ContainerArray = std::vector<Data<T>>;
public:
void f() {
cout << ContainerArray::data() << endl;
}
};
Now it compiles and works. But still, I think this fix is really ugly: why do I have to use XXX::data() everytime I call vector's function? As long as vector is father class, why I can't call it directly?
Does this relate to template class vector, or because I'm inheriting a template class from another template class? I made a quick test to use a normal class to inherit vector:
class Normal : public std::vector<Data<int>>
{
public:
void f() {
cout << data() << endl;
}
};
This time it works, doesn't require that ugly prefix to get compiled. What's the c++ syntax reason behind this?
Thanks a lot!

A trick to enable casting over non-public inheritances

This is a followup related to my previous question where I investigated the problem and found that up- and downcasting seem to be working correctly over public inheritance relations. For example, this code does not even compile:
class A {
};
class B : protected A {
};
int main() {
B b;
static_cast<A*>(&b);
};
G++ gives the following error:
t.cc: In function ‘int main()’:
t.cc:10:21: error: ‘A’ is an inaccessible base of ‘B’
10 | static_cast<A*>(&b);
| ^
However, I think I found the following trick to overcome this limitation. We can cast inside the class, and then export the casting functionality as a public method:
#include <iostream>
class A {
};
class B : protected A {
public:
A* getA() {
return static_cast<A*>(this);
};
static B* fromA(A* a) {
return static_cast<B*>(a);
};
};
int main() {
B b;
// Does not even compile
//std::cout << static_cast<A*>(&b);
// works like charm
std::cout << b.getA() << '\n';
// works also in the reverse direction, although it needs a static method
std::cout << B::fromA(b.getA()) << '\n';
};
I admit it is not very pretty. My tests (in more complex code) show it working, but I am still unsure.
Is it valid C++ code and correct practice?
Conceptually getA is fine. B is choosing to expose the A in it. It can be simplified to return this;, the cast is unnecessary.
I have reservations about fromA, because it is implying that all As are Bs, which might not be true. You should limit the accessibility of fromA to places where you can prove all the As are Bs.
Safe downcast may be done with dynamic_cast.
cppreference on static_cast

error C2079: 'Toto::a' uses undefined class 'foo' [duplicate]

This question already has answers here:
When can I use a forward declaration?
(13 answers)
Closed 7 years ago.
I have error C2079 on compiling following code and I dont understand why. class foo is declared later (forward declaration).
class foo;
//template <typename dataType>
class Toto
{
foo a; //C2079
};
class foo
{
public:
int x;
};
And what is really strange in that issue, is if I uncomment the "template line" (before class Toto declaration), the error disapear. I could use it as a workaround, but I don't understand what happen here.
Following first feedback I got, I tried the following code :
class foo;
//template <typename dataType>
class Toto
{
foo *a; // solve C2079
void otherFunc()
{
a->myFunc(); // C2027
}
};
class foo
{
public:
int x;
void myFunc()
{
};
};
So replacing "foo a" by a pointer "foo * a" solve the compilation error. But adding a function with it's implementation and calling "a->myFunc()" is now prroducing "error C2027: use of undefined type 'foo'". Is it similar issue ? And again "Template" solve it. And yes, I use MSVC compiler.
I dont understand why
Because to create a class where you have a value member, that value member must be defined by the time it's used. (It's necessary e.g. to calculate the size of the class). If that was a pointer or a reference, it would be fine.
And what is really strange in that issue, is if I uncomment the "template line" (before class Toto declaration), the error disapear.
As #Angew points out, this might happen with a non-compliant compiler. For example, g++ outputs proper error diagnostic:
main.cpp:7:9: error: field 'a' has incomplete type 'foo'
foo a;
^

Declare in parent class and define in child [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
So, I have class called A with a prototyped function x. B, C, and D are deriving from A, so the derived classes are having function x also protyped.
Now I want that not every class has function x defined.
How is that possible in C++?
It's against the OOP principles. Inheritance means an is-a relationship. In your example, B, C and D are a kind of A. If A has method x, the others should have also.
If it's not true, x is not really a method of A (but one of it's descendants')
If x should be only accessible from A instead, make it private:
private: void x() {}
You might want to declare x as pure virtual function, e.g.:
virtual void x() = 0;
Making assumptions about what you are asking since every class that derives from A will have x defined. If what you are asking for is that classes B, C and D are implemented in terms of A (i.e. they will utilize the functions of A but cannot be considered an instance of A), you can specify protected or private inheritance of A in B,C, and D.
Example code with this approach might be:
#include <iostream>
class A
{
public:
void x()
{
std::cout << "Hello from A::x" << std::endl;
}
};
class B : protected A
{
public:
};
class C : protected A
{
public:
void x()
{
std::cout << "Hello from C::x" << std::endl;
}
};
class D : public A
{
public:
};
int main(int argc, char **argv)
{
//B instance_of_B;
//instance_of_B.x(); // Will cause a compiler error
C instance_of_C;
instance_of_C.x(); // Will print Hello from C::x
D instance_of_D;
instance_of_D.x(); // will print Hello from A::x
}

Implementing virtual functions without the virtual keyword [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 8 years ago.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Improve this question
My question is as follows:
I want (if it is possible) to "implement" virtual functions without using the "virtual" keyword (out of curiosity - I know the trick with functions pointers in C , I wish to do that in C++ !!).
My "idea" is to have a flag which will be assigned in the constructor in order to indicate which instance this object is.
My questions are:
1)Is it even possible ?
2)If so - what am I doing wrong ? or what is missing ?
I am using g++ which gives me these errors:
#‘B’ has not been declared
#‘C’ has not been declared
#class ‘B’ does not have any field named ‘flag’
#class ‘C’ does not have any field named ‘flag’
This is My suggestion:
#include <iostream>
using namespace std;
class A {
protected:
short flag;
public:
A(int f = 1) : flag(f) {}
void foo()
{
switch (this->flag)
{
case 1: cout << "A " << endl; break;
case 2: B :: foo(); break;
case 3: C :: foo(); break;
}
}
};
class B : public A{
public:
B(int f = 2) : A(f) {}
void foo() {cout << "B " << endl;}
};
class C : public B{
public:
C(int f = 3) : B(f) {}
void foo() {cout << "C " << endl;}
};
int main()
{
A a;
B b;
C c;
A *pb = &b;
A *pc = &c;
a.foo();
pb->foo();
pc->foo();
return 0;
} // end main
Thanks allot (!!) in advance , Guy.
Is it even possible ?
Yes. It may not be advisable, since it's more error-prone than virtual functions, and requires the base class to know about all of the derived classes, but it's certainly possible, and you're almost there.
If so - what am I doing wrong ?
You'll need to move the definition of A::foo out of the class, after the definitions of B and C, so that it can use those classes.
You'll need an explicit downcast to access member functions of derived classes:
static_cast<B*>(this)->foo();