So I’m in the process of creating an event style system, but this code breaks when I declare a connection as a pointer.
#include <iostream>
#include <chrono>
#include <thread>
using namespace std;
using namespace chrono_literals;
template<typename... Types>
struct Connection {
void Connect(void(*f)(Types...)) {
Callback = f;
}
void Fire(Types... Args) {
Callback(Args...);
}
private:
void(*Callback)(Types...);
};
int main() {
cout << boolalpha;
Connection<char>* event;
event->Connect([](char key){
cout << "Event fired!" << '\n';
cout << "Key: " << key << '\n';
});
event->Fire('a');
}
This code works when the connection isn’t a pointer, and instead of using the -> operator, I’d use use the regular . operator, but I’d like to declare them as pointers so I can use the -> .
One very strange thing to note is when I do something like this
Connection<char> e;
Connection<char>* event;
// ... rest of code
Then this actually runs, I don’t know why it’s like that.
You don't "declare a class as a pointer". That's not a thing. You have a class (which is a type), then you declare an instance of that class (i.e. an object). Optionally you can manage that object using pointers.
But you didn't actually create any instance. All you did was create a pointer, uninitialised, not pointing to anything, then tried to dereference it to use the object it points to… which doesn't exist.
There's no need for dynamic allocation here anyway; forget the pointer and just declare a nice Connection<Event>. Using pointers "because it looks nicer" is, to put it kindly, not the best way to write a C++ program.
Section 9(1/4) out of 11 of my c++ introduction webclass;
I have no idea what I'm doing.
I'm unsure even of what terms to search for(first touch with OOP).
-
I need to print the cin in main with a function in a class,
So far I have come up with a class with a string variable and a function that do nothing;
#include <iostream>
#include <string>
using namespace std;
class printclass
{
public:
string array;
void print();
};
void printclass::print()
{
cout << array;
}
Main program(cannot be edited);
int main()
{
char array[50];
cout << "Enter string:";
cin.get(array, 50);
printclass printer;
printer.print(array);
}
It is my understanding that the printclass printer; creates an object 'printer' with the printclass class and thus knows how to use the functions in the class
on sort-of a blank page that is declared with the call, am I far off?
How do I print the value of the array in main with the function?
The exercise has been translated from finnish, please excuse blunt grammar and user stupidity.
Thank you for your time!
am I far off?
Kinda. You've incorrectly assumed the interface of your printclass. Here's a correct one1 from the example posted:
class printclass {
public:
printclass();
void print(const char* str);
};
From that it's quite easy to spot your mistake; you've assumed that your class has to store the array to print, while the interface passes it directly. It's enough to implement the print in terms of str without any member variables:
void printclass::print(const char* str) { // could be const
std::cout << str;
}
Note: the constructor can of course be left alone and it will default to what you want.
1One of many possible interfaces, but I've picked the most likely.
I've been trying to convince myself that that objects of the same type have access to each others private data members. I wrote some code that I thought would help me better understand what is going on, but now I am getting an error from XCODE7 (just 1), that says that I am using the undeclared identifier "combination."
If someone could help me understand where I have gone awry with my code, I would love to learn.
My code should simply print false, if running correctly.
#include <iostream>
using std::cout;
using std::endl;
class Shared {
public:
bool combination(Shared& a, Shared& b);
private:
int useless{ 0 };
int limitless{ 1 };
};
bool Shared::combination(Shared& a,Shared& b){
return (a.useless > b.limitless);
}
int main() {
Shared sharedObj1;
Shared sharedObj2;
cout << combination(sharedObj1, sharedObj2) << endl;
return 0;
}
combination is a member function of the class Shared. Therefore, it can only be called on an instance of Shared. When you are calling combination, you are not specifying which object you are calling it one:
cout << combination(sharedObj1, sharedObj2) << endl;
^^^
Instance?
The compiler complains because it thinks you want to call a function called combination, but there is none.
So, you'll have to specify an instance:
cout << sharedObj1.combination(sharedObj1, sharedObj2) << endl;
In this case however, it doesn't matter on which instance it is being called on, so you should make combination static, so you can do
cout << Shared::combination(sharedObj1, sharedObj2) << endl;
Fairly simple question here, whats the best way to fill a vector outside of a function in a class .cpp file? currently i'm attempting the following which is not working:
std::vector<Player> midfielder(8);
midfielder.at(0) = Midfielder("Default ",0,"Midfielder");
midfielder.at(1) = Midfielder("David Armitage ",1,"Midfielder");
midfielder.at(2) = Midfielder("Tom Rockliff ",2,"Midfielder");
midfielder.at(3) = Midfielder("Gary Ablett ",3,"Midfielder");
midfielder.at(4) = Midfielder("Dyson Heppel ",4,"Midfielder");
midfielder.at(5) = Midfielder("Scott Pendlebury",5,"Midfielder");
midfielder.at(6) = Midfielder("Michael Barlow ",6,"Midfielder");
midfielder.at(7) = Midfielder("Jack Steven ",7,"Midfielder");
To provide context, 'Midfielder' is a class that inherits from the 'Player' class.
TeamManagment.h
#ifndef TEAMMANAGEMENT_H
#define TEAMMANAGEMENT_H
#include <vector>
#include "Player.h"
#include "Midfielder.h"
#include <string>
class TeamManagement
{
public:
TeamManagement();
void Display_Players();
};
#endif // TEAMMANAGEMENT_H
TeamManagement.cpp
#include <iostream>
#include <string>
#include <vector>
#include "Player.h"
#include "Midfielder.h"
#include "TeamManagement.h"
using namespace std;
TeamManagement::TeamManagement()
{
}
std::vector<Player> midfielder(8);
//errors start occurring on line below: 'midfielder' does not name a type
midfielder.at(0) = Midfielder("Default ",0,"Midfielder");
midfielder.at(1) = Midfielder("David Armitage ",1,"Midfielder");
midfielder.at(2) = Midfielder("Tom Rockliff ",2,"Midfielder");
midfielder.at(3) = Midfielder("Gary Ablett ",3,"Midfielder");
midfielder.at(4) = Midfielder("Dyson Heppel ",4,"Midfielder");
midfielder.at(5) = Midfielder("Scott Pendlebury",5,"Midfielder");
midfielder.at(6) = Midfielder("Michael Barlow ",6,"Midfielder");
midfielder.at(7) = Midfielder("Jack Steven ",7,"Midfielder");
//errors stop occurring here
void TeamManagement::Display_Players(){
cout<<"Position Name ID"<<endl;
for (int i=1;i<8;i++)
{
cout<<midfielder[i].Player_Details()<<" "<<midfielder[i].Get_player_id()<<endl;
}
}
The first problem is that you cannot perform assignment like that outside of a function. You must use construction or initialization.
With C++98 you cannot populate/initialize a vector outside of a function.
With C++11/14 you can populate one using initializer syntax:
#include <iostream>
#include <vector>
struct Thing {
int m_i, m_j;
Thing(int i, int j) : m_i(i), m_j(j) {}
};
std::vector<Thing> things {
{ 1, 2 }, { 2, 3 }
};
int main() {
std::cout << "things[0].m_j = " << things[0].m_j << '\n';
}
But std::vector won't like you trying to put "Midfielder"s into a vector of Player. Lets use an SSCCE to reconstruct the damage you're doing:
#include <iostream>
struct Base {
int i;
};
struct Derived : public Base {
int j;
};
int main() {
std::cout << "Base size = " << sizeof(Base) << '\n';
std::cout << "Derived size = " << sizeof(Derived) << '\n';
}
This tells us that Base and Derived have a different size. But you're trying to put these two objects into the same container because they're related. Round peg and square peg are related... They won't fit into the same hole, and this is the problem we have now.
The vector creates space in memory for your elements based on the type you supply, and then it requires you to pass it exactly that type to populate those spaces with, or a type that has a conversion mechanism to the storage type.
If you want to have a container of different types, you'll need to use pointers, but then you're going to run into the problem that what you get back will be a pointer to the base type and you will need to provide yourself with a way to distinguish different player types.
See Store derived class objects in base class variables for the C++98 approach. In modern C++ (11 and 14) you should use smart pointers, e.g.
std::vector<std::unique_ptr<Base>>
std::vector<std::shared_ptr<Base>>
Presumably default constructing a Midfielder doesn't make a lot of sense, so you can reserve the memory, then emplace_back into the vector.
std::vector<Player> midfielder {};
midfielder.reserve(8);
midfielder.emplace_back("Default ",0,"Midfielder");
midfielder.emplace_back("David Armitage ",1,"Midfielder");
midfielder.emplace_back("Tom Rockliff ",2,"Midfielder");
midfielder.emplace_back("Gary Ablett ",3,"Midfielder");
midfielder.emplace_back("Dyson Heppel ",4,"Midfielder");
midfielder.emplace_back("Scott Pendlebury",5,"Midfielder");
midfielder.emplace_back("Michael Barlow ",6,"Midfielder");
midfielder.emplace_back("Jack Steven ",7,"Midfielder");
midfielder.at(0) = Midfielder("Default ",0,"Midfielder"); is a statement. You've put that and similar statements in (global) namespace scope. That's your bug. Only declarations may be in namespace scope. You must put your statements inside a function.
The error message stems from the fact that declarations which don't start with a keyword start with a type name. Since midfielder is not a keyword, the compiler expects it to be a type name but it isn't one, so you get the error.
I want to output the values of the private class members Bankcode and AgentName. How can I do this from within my main() function, or in general, outside of the BOURNE class.
My initial code attempts are below:
#include <iostream>
#include <string>
using namespace std;
class BOURNE
{
string Bankcode ={"THE SECRET CODE IS 00071712014"} ; /*private by default*/
string AgentName={"Jason Bourne"}; /*private by default*/
public:
void tryToGetSecretCodeandName(string theName ,string theCode); //trying to get the private
void trytoGetAgentName( string name); // try to get name
};
//***********************defining member function**************************************
void BOURNE::tryToGetSecretCodeandName(string theName, string theCode) //member defining function
{
Bankcode=theCode; //equalling name to the code here
AgentName=theName; //the samething here
cout<<theCode<<"\n"<<theName; //printing out the values
}
//************************main function*****************************
int main()
{
BOURNE justAnyObject; //making an object to the class
justAnyObject.tryToGetSecretCodeandName();
return 0;
}
Third Answer
Your code has two 'getter' style functions, but neither one takes no arguments. That is, both of your functions require arguments to be passed.
Your main function is calling get...CodeandName(), which has no arguments. As such, you get a compiler error, probably complaining about valid signatures, or arguments passed.
Edited Answer
If you only want to get the values, the typical (as far as I am aware) implementation is something like
std::string BOURNE::getCode()
{
return Bankcode;
}
std::string BOURNE::getName()
{
return AgentName;
}
int main()
{
BOURNE myAgent;
cout<< "The agent's name is : " << myAgent.getName() << endl;
cout<< "The agent's code is : " << myAgent.getCode() << endl;
}
Original Answer, left in because I feel like it's more useful
I suspect what you're asking is if you could do something like
void BOURNE::tryToGetSecretCodeandName(string theName, string theCode)
{
if (Bankcode == theCode) {
cout<< "You correctly guessed the code : " << Bankcode << endl;
}
if (AgentName == theName) {
cout << "You correctly guessed the agent's name : " << AgentName << endl;
}
}
This will allow you to repeatedly guess at the name, and get output when you're correct.
If you wanted to disable this kind of guessing, then you could consider creating a new class (possibly derived from/based on std::string - but see this question for reasons to be careful!) and implement an operator== function which always returned false.