Declare an object inside a C++ class [duplicate] - c++

I'm beginning to learn C++. In the IDE codeblocks, this compiles:
#include <iostream>
using namespace std;
struct A {};
struct B {
A a;
}
void hi() {
cout << "hi" << endl;
}
int main() {
hi();
return 0;
}
But this doesn't:
struct B {
A a;
}
struct A {};
int main() {
hi();
return 0;
}
void hi() {
cout << "hi" << endl;
}
It gives me the errors:
error: 'A' does not name a type
error: 'hi' was not declared in this scope
Should class/function order matter in C++? I thought it doesn't. Please clarify the issue.

Yes, you must at least declare the class/function before you use/call it, even if the actual definition does not come until afterwards.
That is why you often declare the classes/functions in header files, then #include them at the top of your cpp file. Then you can use the classes/functions in any order, since they have already been effectively declared.
Note in your case you could have done this. (working example)
void hi(); // This function is now declared
struct A; // This type is now declared
struct B {
A* a; // we can now have a pointer to it
};
int main() {
hi();
return 0;
}
void hi() { // Even though the definition is afterwards
cout << "hi" << endl;
}
struct A {}; // now A has a definition

Related

How to call member functions from a class nested within a namespace?

I want to call a class member function that's nested within a namespace from a different file, but I don't know how.
For example:
How to call a class member function someFunc() that's located in code.h and nested within namespace "program" from main.cpp.
//code.h
#include <iostream>
namespace program
class test {
private:
int x;
public:
test()
{
test::x = 10;
};
someFunc()
{
cout << x << " ";
};
};
There are some problems in your code
#include <iostream>
namespace program { // <-- braces missing
class test
{
private:
int x;
public:
test()
{
test::x = 10; // <-- test:: is unnecessary but no error
};
void someFunc() // <-- return type missing
{
std::cout << x << " "; // <-- namespace std missing
};
};
} // <-- braces missing
int main() {
program::test t;
t.someFunc();
}

C++ struct declared in function visible in main

why does this code work? with c++14
// Example program
#include <iostream>
#include <string>
using namespace std;
auto fun()
{
struct a
{
int num = 10;
a()
{
cout << "a made\n";
}
~a()
{
cout << "a destroyed\n";
}
};
static a a_obj;
return a_obj;
}
int main()
{
auto x = fun();
cout << x.num << endl;
}
how is the type a visible in main? if i change auto x= to a x= it obviously doesn't compile, but how does main know about the type a?
The static declaration is there since I was trying to test for something else but then I stumbled upon this behavior.
Running it here: https://wandbox.org/permlink/rEZipLVpcZt7zm4j
This is all surprising until you realize this: name visibility doesn't hide the type. It just hides the name of the type. Once you understand this it all makes sense.
I can show you this without auto, with just plain old templates:
auto fun()
{
struct Hidden { int a; };
return Hidden{24};
}
template <class T> auto fun2(T param)
{
cout << param.a << endl; // OK
}
auto test()
{
fun2(fun()); // OK
}
If you look closely you will see this is the same situation as yours:
you have a struct Hidden which is local to fun. Then you use an object of type Hidden inside test: you call fun which returns a Hidden obj and then you pass this object to the fun2 which in turn has no problem at all to use the object Hidden in all it's glory.
as #Barry suggested the same thing happens when you return an instance of a private type from a class. So we have this behavior since C++03. You can try it yourself.
C++14 is made to be more and more tolerant with auto. Your question is not clear, because you're not stating what the problem is.
Now let's tackle your question differently: Why does it not work with a x = ...?
The reason is that the struct definition is not in the scope of the main. Now this would work:
// Example program
#include <iostream>
#include <string>
using namespace std;
struct a
{
int num = 10;
};
auto fun()
{
static a a_obj;
return a_obj;
}
int main()
{
a x = fun();
cout << x.num << endl;
}
Now here it doesn't matter whether you use a or auto, because a is visible for main(). Now auto is a different story. The compiler asks: Do I have enough information to deduce (unambiguously) what the type of x is? And the answer is yes, becasue there's no alternative to a.

C++ header issue involving functions and scope

My problem is in the following C++ code. On the line with the 'cout' I get the error:
"'number' was not declared in this scope".
.h
using namespace std;
class a{
int number();
};
.cpp
using namespace std;
#include <iostream>
#include "header.h"
int main(){
cout << "Your number is: " << number() << endl;
return 0;
}
number(){
int x = 1;
return x;
}
Note: I'm aware this isn't the cleanest code. I just wanted to get the function working and refresh my memory on how to use headers.
For minimal fix, three basic changes are necessary.
Proper implementation of the number() method
int a::number() {
int x = 1;
return x;
}
Proper invocation of the number() method
a aObject;
cout << "Your number is: " << aObject.number() << endl;
There are many other enhancements possible though.
Addition, as pointed out by #CPlusPlus, usable scope of number() method, for example declaring it public
class a{
public:
int number();
};
Try this in your cpp file
using namespace std;
#include <iostream>
#include "header.h"
void a::number()
{
int x = 1;
return x;
}
int main()
{
cout << "Your number is: " << a().number() << endl;
return 0;
}
As for your header file replace class with a struct. The reason you are getting this error is because the compiler cant find the variable number. It is actually a method of a class.The reason you are replacing the class with a struct is because by default everything in a struct is public. So your header file called header.h should look like this
using namespace std;
struct a
{
int number();
};
There are three issues with your code.
The definition of the function number().
As you declared, it is a member function of the class "a". In your .cpp, the class name should be used as a prefix to the function. I mean,
a::number(){
int x = 1;
return x;
}
As the function is a member of the class "a", there are only two ways of accessing it,
If the function is a static function in the class, you can access it with :: operator. Like a::number().
If the function is not a static function, that is true in your case, you should instantiate the object out of the class "a" and they use "." operator with the reference. I mean,
a obj;
obj.number().
Your function number() is declared in private scope. You may recall that by default the scope is a class is private unless you specify public or protected. So the private function number() cannot be used outside the declared class unless there is a friend to it.
Below the code that I fixed,
.h
using namespace std;
class a{
public:
int number();
};
.cpp
using namespace std;
#include <iostream>
#include "header.h"
a::number(){
int x = 1;
return x;
}
int main(){
a obj;
cout << "Your number is: " << obj.number() << endl;
return 0;
}

Function "was not declared in this scope"

I'm new to C++ and get a beginner's mistake:
myclass.cpp: In function ‘int main()’:
myclass.cpp: 14:16: error: ‘func’ was not declared in this scope
This is the code:
#include <iostream>
using namespace std;
class MyClass{
public:
int func(int);
};
int MyClass::func(int a){
return a*2;
}
int main(){
cout << func(3);
}
I hope you can help me.
int main(){
cout << func(3);
}
func is not a global function; it is a member function of the class. You need an instance of the class to access it.
For example:
int main()
{
MyClass obj;
std::cout<< obj.func(3);
}
func is a member function, so it must be invoked through an object. For example:
int main()
{
MyClass obj;
std::cout << obj.func(3); // 6
}
In your example, you treated it as a free function, so the compiler looked for a function with that name. Since it could not find it, it issued a compiler error.
func is a member function of MyClass. To call it, you need an object of MyClass type to invoke it on:
int main(){
MyClass m; // Create a MyClass object
cout << m.func(3);
}
Alternatively, you could make func a static member function, which means that it is not associated with any particular instance of the class. However, you would still need to qualify its name as belonging to the MyClass class:
class MyClass{
public:
static int func(int);
};
int MyClass::func(int a){
return a*2;
}
int main(){
cout << MyClass::func(3);
}

How to have a c++ object with a method that takes argument the enclosing class?

I am trying to figure out if there's any known pattern/idiom in c++ for what I am trying to do here. Class A must be composed of an object that has a function whose argument must also be of type A. The following code doesn't compile since typeid may not be used in a constant expression. Any suggestions?
#include <iostream>
#include <typeinfo>
using namespace std;
template <typename T>
struct B {
int f(T& i) { cout << "Hello\n"; }
};
class A {
B<typeid(A)> b;
};
int main()
{
A k;
}
Your stated requirements don't need templates at all, just a forward declaration:
#include <iostream>
class A; // forward declare A
struct B {
int f(A &i); // declaration only, definition needs the complete type of A
};
class A {
B b;
};
int B::f(A &i) { std::cout << "Hello\n"; } // define f()
int main()
{
A k;
}
You are looking for B<A> b; The following program compiles without error or warning on g++ 4.4.3.
#include <iostream>
#include <typeinfo>
using namespace std;
template <typename T>
struct B {
int f(T& i) { cout << "Hello\n"; return 0; }
};
class A {
public:
B<A> b;
};
int main()
{
A k;
return k.b.f(k);
}
Note: If you are using templates only to avoid forward declaration, my solution is wrong. But, I'll leave it here in case you are using templates for some other legitimate reason.