calling a struct member declared in a class - c++

I am trying to place functions inside a struct which is part of a class (here named menu) so I can modify the struct inside of a dedicated setup cpp file (I am trying to do this so I can modify all of the functions I want in my application in a single source file instead of changing stuff in all of my cpp files):
// Menu.h
class menu
{
public:
menu();
struct pages
{
void print_page_1();
void print_page_2();
};
};
// Setup.cpp
struct menu::pages
{
void print_page_1()
{
// ...
}
void print_page_2()
{
// ...
}
};
Then I get an error when trying to call a function within my struct:
int main()
{
menu myMenu();
myMenu.pages.print_page_1(); // error: type name is not allowed
}
What does this error mean and how can I avoid it?
Thank you!

pages is the name of the struct, it's not an object. You need an object of type pages inside menu.
Otherwise, you can have static methods inside pages and call those without creating objects.
Example (live):
#include <iostream>
struct S
{
struct P
{
void print()
{
std::cout << "Hello from P!\n";
}
} p; // object of P
struct Q
{
static void print()
{
std::cout << "Hello from Q!\n";
}
};
};
int main()
{
S s;
s.p.print();
S::Q::print();
return 0;
}
Output:
Hello from P!
Hello from Q!

You need to declare a pages object in menu.
#include <iostream>
class menu
{
std::string p1 = "1";
std::string p2 = "2";
public:
struct pages
{
menu& m;
pages(menu &m):m(m){
}
void print_page_1();
void print_page_2();
} pages;
menu():pages(*this){
}
};
void menu::pages::print_page_1()
{
std::cout << m.p1;// ...
}
void menu::pages::print_page_2()
{
std::cout << m.p2;// ...
}
int main() {
menu myMenu;
myMenu.pages.print_page_1();
// your code goes here
return 0;
}

Related

bind class member funtion to std::function not need check parameters?

why gcc 9.4 not check parameters when bind a class member funtion to a std::function viriable, but check when bind a global function? here is example code, CreateRpcFun has a parameter, but Test member function print doesn't have any other parameters except this, bind print to CreateRpcFun works well, but global funtion print2 cannot, can anybody explain why?
#include <functional>
#include <iostream>
#include <string>
using namespace std;
using CreateRpcFun = std::function<void(const string &)>;
class Test {
public:
Test() : str_("nihao!") {}
// bind print to CreateRpcFun passed compile
void print() { cout << str_ << endl; }
private:
string str_;
};
class Holder {
public:
CreateRpcFun CreateRpc;
};
class Other {
public:
Other(Holder h, string str) : h_(h), str_(str) {}
void run() { h_.CreateRpc("world!"); }
private:
Holder h_;
string str_;
};
void print1(const string &str) { cout << str << endl; }
void print2() { cout << "magic" << endl; }
int main() {
Test t;
Holder h;
h.CreateRpc = std::bind(&Test::print, &t);
Other o(h, "hhhh");
o.run();
h.CreateRpc = &print1;
h.CreateRpc("test");
// h.CreateRpc = &print2; // compile error
// h.CreateRpc("test");
}

C++ Creating a function, like a variable, change its body later and then call it later

I'm trying to create a dummy function inside of a class, whichs' body will be changed later in int main(). And then I'd like to call this body changed func in the class. Is there a way to achieve this?
Something like this:
class Animation {
public:
//Don't know what to write at the next line
function<void>/*?*/ whenCompleted = []() mutable { /* Dummy func. */ };
.
.
.
void startAnimation() { /* Do stuff, then */ animationEnded(); }
void animationEnded() { whenCompleted(); }
}score;
int main(){
score.whenCompleted = { /* new body for whenCompleted() */ }
score.startAnimation();
}
You basically have the right idea
#include <functional>
#include <iostream>
class Animation
{
public:
std::function<void()> whenCompleted;
void startAnimation() { animationEnded(); }
void animationEnded() { whenCompleted(); }
};
int main()
{
Animation score;
score.whenCompleted = [](){ std::cout << "all done"; };
score.startAnimation();
}
Will output
all done
You could also add a constructor for Animation that accepts a function to initialize whenCompleted with
Animation(std::function<void()>&& onCompleted) : whenCompleted(onCompleted) {}
which would modify main to
int main()
{
Animation score{[](){ std::cout << "all done"; }};
score.startAnimation();
}

not declare in scope when compiled g++

This is my A.h file
class A
{
public:
void menuChoice();
void displaystartingMenu(); //EDIT
};
This is my A.cpp file
#include "A.h"
void displaystartingMenu()
{
cout<<"Please enter your choice:";
}
void A::menuChoice()
{
displaystartingMenu();
cout<<"Hello"<<endl;
}
int main()
{
A a;
a.menuChoice();
}
i tried to put
void menuChoice();
on the top of my cpp file but it still won't compile . it gives me error
In function ‘int main()’: A.cpp:112:13: error: ‘menuChoice’ was not declared in this scope menuChoice();
How do I compile : g++ A.cpp A.h
By right I don't need to even declare the function of top of the cpp because I have already declare it in my header file and I have included in my .cpp. What went wrong here?
EDIT:
Error :
In function `A::menuChoice()':
A.cpp:(.text+0x229): undefined reference to `A::displaystartingMenu()'
Option 1: Make an A instance and call that instance's menuChoice method:
#include <iostream>
class A {
public:
void menuChoice();
};
void A::menuChoice() {
std::cout << "Hello" << std::endl;
}
int main() {
A a;
a.menuChoice();
return 0;
}
Option 2: Make menuChoice a static method and call it as A::menuChoice:
#include <iostream>
class A {
public:
static void menuChoice();
};
void A::menuChoice() {
std::cout << "Hello" << std::endl;
}
int main() {
A::menuChoice();
return 0;
}
Edit: Addressing the new problem, when you tried to define A::displaystartingMenu you wrote:
void displaystartingMenu() {
// ...
}
It must be defined like this:
void A::displaystartingMenu() {
// ...
}
menuChoice is a non static member function of class A. In order to call it you need to instantiate an object A, as follows
int main()
{
A a;
a.menuChoice();
return 0;
}

Any Example that Prove Initializer List Call before Constructor C++

I have searched but still didn't get easy and proper answer, Below is my code.
#include <iostream>
using namespace std;
class Parent
{
private:
int a;
public:
Parent():a(3) { cout << a; }
};
int main()
{
Parent obj;
return 0;
}
Can you add additional lines of code that can prove or show me that initializer list call before constructor?
I would modify you code ever so slightly:
#include <iostream>
using namespace std;
class Parent
{
public:
int a;
public:
Parent():a(3){
a = 4;
}
};
int main()
{
Parent obj;
cout << obj.a;
return 0;
}
The output is 4, thus a was initialized with 3 and then assigned 4.
Simply add data member, which has constructor, which prints something. Example:
#include <iostream>
using namespace std;
struct Data {
Data(int a) {
cout << "Data constructor with a=" << a << endl;
}
};
class Parent
{
private:
Data a;
public:
Parent():a(3){
cout << "Parent constructor" << endl;
}
};
int main()
{
Parent obj;
return 0;
}
Output:
Data constructor with a=3
Parent constructor
Conclusion: Data constructor was called before constructor body of Parent.
You don't get variable "a" value 10 in this program , a assigned before constructor method called .
#include<iostream>
using namespace std;
class Test
{
public:
int a,b;
public:
Test():a(b){
b=10;
}
};
int main()
{
Test obj;
cout<<"a :"<<obj.a<<" b:"<<obj.b;
return 0;
}
This is best shown with multiple classes:
#include <iostream>
class A
{
public:
A()
{
std::cout << "Hello World!" << std::endl;
}
};
class B
{
private:
A* a;
public:
// Call a's constructor
B():a(new A)
{
// Some code
}
~B()
{
delete a;
}
};
int main()
{
B obj;
return 0;
}

How to call a function which belongs to a class in C++?

I am trying to call the function hello which belongs to the class program1
#include <iostream>
using namespace std;
class program1
{
program1();
~program1();
hello();
}
program1::hello()
{
cout<<"hello";
}
int main()
{
program1.hello(); //Call it like a normal function...
cin.get();
}
Names inside a class are private by default.
class program1 {
public:
program1();
~program1();
void hello() ;
};
// ...
int main(int, char **) {
program1 myProgram;
myProgram.hello();
return 0;
}
Alternatively, you can invoke a method on a temporary:
int main(int, char **) {
program1().hello();
return 0;
}
but that's probably for later in the semester.
you forgot to create an object:
int main()
{
program1 p1;
p1.hello();
}
Class definition should end with ;
Secondly, you need to instantiate class to call members on it. ( i.e., creation of an object for the class )
In C++, methods should have return type.
program1::hello(); // method should have a return type.
class members and methods are private by default, which means you cannot access them outside the class-scope.
So, the class definition should be -
class program1
{
public: // Correction 1
program1();
~program1();
void hello(); // Correction 2
};
void program1::hello() // Need to place return type here too.
{
cout<<"hello";
}
Now on creation of object for class program1, it's method hello() can be called on it.
This version is edited. (make sure you include all the body of the methods)
#include <iostream>
using namespace std;
class program1
{
public: // To allow outer access
program1();
~program1();
void hello(); // The void
}; // Don't miss this semicolon
void program1::hello() // The void
{
cout<<"hello";
}
int main()
{
program1 prog; // Declare an obj
prog.hello(); //Call it like a normal function...
cin.get();
}
I noticed that you left out return type for your hello() function.
If you want to call hello() as a member function, then as suggested you should create an object to it.
program1 prog;
prog.hello();
If you want to call it without an object, the you should use static function.
class program1
{
public: // To allow outer access
program1();
~program1();
static void hello(); // The void
}
then you can call it this way:
program1::hello();
Therefore the working code should be this way:
#include <iostream>
using namespace std;
class program1 {
public:
void hello();
}; // Don't miss this semicolon
class program2 {
public:
void static hello(); // to demonstrate static function
}; // Don't miss this semicolon
void program1::hello() {
cout << "Hello, I'm program1." << endl;
}
void program2::hello() {
cout << "Hello, I'm program2." << endl;
}
int main(void) {
program1 prog1;
prog1.hello(); // Non-static function requires object
program2::hello(); // Static function doesn't
return 0; // Return 0
}