main.cpp:
#include "Login.h"
int main () {
Login();
}
Login.h:
#ifndef LOGIN_H
#define LOGIN_H
#include <string>
#include <iostream>
using namespace std;
class Login
{
public:
Login ();
string getInput () {
return input;
}
void setInput (string x) {
x=input;
}
private:
string input;
};
#endif
Login.cpp:
#include "Login.h"
Login::Login ()
{
Login lo;
lo.setInput("hello");
cout << lo.getInput();
};
I'm just learning to program and I'm trying to make a simple program to display input, but to use a class and object to do it, so I can learn how and ultimately make a program that starts with a login (hence all the "login" names).
When I run this it just crashes, and I have no idea why, or how i would search for a solution to this online, because I don't know even remotely what the problem is.
My question is two-fold:
1. Why is this just crashing?
2. How could I set the parameter in lo.setInput to a user input? (cin)
For 1,
Login::Login()
{
Login lo; // here
You're recursively-calling Login constructor infinitely. When Login lo, the constructor Login::Login is called. it makes its new Login object, and repeat...
Probably you want this:
Login::Login()
{
setInput("hello");
cout << getInput();
}
For 2, just receive input and call with it.
string str;
getline(cin, str);
setInput(str);
In addition, C++ is too hard for newbies to study at first. I recommend you to start with other easier language, such as C, python, etc.
The problem is that your constructor recursively calls itself when it creates within its body local object lo
Login::Login ()
{
Login lo;
lo.setInput("hello");
cout << lo.getInput();
};
Change it the following way
Login::Login ()
{
setInput("hello");
cout << getInput();
};
Though it would be better to define it like (or to allow the compiler to define it itself)
Login::Login () {}
and in main to write
Login lo;
lo.setInput("hello");
cout << lo.getInput();
Also function setInput is invalid
void setInput (string x) {
x=input;
}
There must be
void setInput (string x) {
input = x;
}
The class could be defined like
class Login
{
public:
Login() = default;
Login( const std::string &s ) : input( s ) {}
std::string getInput () const { return input; }
void setInput( const std::string &s ) { input = s; }
private:
std::string input;
};
You may want to create an instance of the Login class and use its methods:
int main(void)
{
Login my_login;
cout << my_login.getInput();
return 0;
}
Another possibility is to create static methods within the Login class. This would essentially be like grouping functions and variables into one package:
class Login
{
public:
static std::string getLoginText(void)
{
std::string text;
cout << "Enter login ID: ";
cin >> text;
return text;
}
};
int main(void)
{
std::string login_text;
login_text = Login::getLoginText();
cout << "Person " << login_text << " is logged in\n";
return 0;
}
Your original main program is confusing as to whether you want to create a temporary instance of the Login class, or call a function called Login. The above techniques make your code more readable by explicitly stating your intentions, rather than relying on unconventional techniques.
Related
I have a class called Account with below parameters:
Account::Account(string ibanCode, string paramOwner, double amount) {}
I have created a vector consisting of class Accounts inside main function:
accs.push_back(Account(fullName, iban, value));
I want to write a function to print all the Account values in my vector by a class member function called displayAll() , and so far I tried this:
void Account::displayAll()
{
for (int i = 0; i < accs.size(); i++)
{
cout << accs[i].displayBalance() << endl;;
}
}
And I want to write it inside the class file. Do you have any suggestions?
I think making it a member would be extremely complicated, the best option should be using a normal function that can access the parameters.
#include <iostream>
#include <vector>
using namespace std;
struct Account {
Account (string ibanCode, string paramOwner, double amount) : _amount(amount), _ibanCode(ibanCode), _paramOwner(paramOwner) {};
string _ibanCode;
string _paramOwner;
double _amount;
};
void DisplayAll (const vector<Account>& Accs) {
for (const auto& Acc : Accs) {
cout << Acc._ibanCode<<' '<<Acc._paramOwner<<' '<< Acc._amount<<'\n';
}
return;
}
int main () {
vector<Account> Accs;
Accs.push_back(Account("SomeCode", "SomeOwner", 2.0));
Accs.push_back(Account("SomeOtherCode", "SomeOtherOwner", 3000.42));
DisplayAll(Accs);
}
To avoid complicating the answer too much I made a struct but you can either make the DisplayAll function a friend of the class or make some getters.
Here's my code:
#include <iostream>
#include <string>
class Human
{
public:
std::string * name = new std::string();
void introduce();
};
void Human::introduce()
{
std::cout << "Hello, my name is " << Human::name << std::endl;
}
int main()
{
Human * martha;
martha->name = new std::string("Martha");
martha->introduce();
return 0;
}
Well, it's supposed to print a message out like:
"Hello, my name is Martha" but it doesn't print neither the "Hello, my name is" string or the "Martha" name. Why does it occur?
The fix is simple and is to completely remove all pointers; see the code below. There are a number of issues with your code that I could address in detail, including memory leaks, uninitialized variables, and general misuse of pointers, but it seems that you're possibly coming from a different language background and should spend time learning good practice and the important semantics and idioms in modern C++ from a good C++ book.
#include <iostream>
#include <string>
class Human
{
public:
std::string name;
void introduce();
};
void Human::introduce()
{
std::cout << "Hello, my name is " << name << std::endl;
}
int main()
{
Human martha;
martha.name = "Martha";
martha.introduce();
return 0;
}
Few modifications are required to the code.
Updated code along with the comments to the change made are included below.
#include <iostream>
#include <string>
class Human
{
public:
//Removed pointer to a string
//Cannot have an instantiation inside class declaration
//std::string * name = new std::string();
//Instead have a string member variable
std::string name;
void introduce();
};
void Human::introduce()
{
//Human::name not required this is a member function
//of the same class
std::cout << "Hello, my name is " << name << std::endl;
}
int main()
{
Human *martha = new Human();
//Assign a constant string to string member variable
martha->name = "Martha";
martha->introduce();
return 0;
}
As suggested by #alter igel - The Definitive C++ Book Guide and List would be a good place to start.
#include <iostream>
#include <string>
class Human {
public:
void Human(std::string* n) { name = n; }
void introduce();
private:
std::string* name;
};
void Human::introduce() {
std::cout << "Hello, my name is " << name << std::endl;
}
int main() {
Human* martha = new Human(new std:string("Martha"));
martha->introduce();
return 0;
}
Try that. The difference is that you don't initialise the variable in the class definition, and you initialise the name with the constructor. You can split the method definition out into it's own section, but it's only one line and is fine being inside the class definition.
I'm currently defining a few properties for a class in C++ but I'm running into trouble when using type string as opposed to something like int or double. For example:
private:
int LOT;
public:
int getLOT() {
return LOT;
}
void setLOT(int value) {
LOT = value;
}
works fine, but:
private:
string name;
public:
string getName() {
return name;
}
void setName(string value) {
name = value;
}
throws these errors:
https://s26.postimg.org/wm5y7922h/error.png
The file (a header) looks something like this:
#include "general.h" // a header which includes all my other #includes
// which, yes, does include <string>
class MyClass
{
private:
string name;
public:
string getName() {
return name;
}
void setName(string value) {
name = value;
}
// other properties similar to the above
}
The purpose is to access the variable like this:
cout << "Enter your name: ";
cin >> MyClass.setName();
cout << "\nHello, " << MyClass.getName();
// although this isn't exactly how it'll be used in-program
If anyone could provide help with what I'm doing wrong or a better way to go about a string property (as, like I mentioned before, other types work fine) it would be greatly appreciated. Thanks.
string is part of std namespace.
You must use std::string instead of string or add using namespace std; (what I would not recommend you to do in your header file, read "using namespace" in c++ headers).
I want to get a specific object in a class in C++. I looked into multiple sites and it seems my question is unique. Okay here's my code.
In House.h
#include <string>
using namespace std;
class House
{
string Name;
int Health;
public:
House(string a, int h);
void GetHouseStats();
void DamageHouse(int d);
~House();
};
in House.cpp
#include "House.h"
#include <iostream>
House::House(string a, int h)
{
Name = a;
Health = h;
}
void House::DamageHouse(int d) {
Health -= d;
cout << "Your " << Name << " has " << Health << " left."<<endl;
}
void House::GetHouseStats() {
cout << Name<<endl;
cout << Health;
}
House::~House()
{
}
in Source.cpp
#include <iostream>
#include "House.h"
using namespace std;
int main()
{
House Kubo("Bahay Kubo", 2);
Kubo.DamageHouse(1);
}
I have House Kubo as my first object. I would like to save the person's houses into a file but my problem is How can I pass the object's name into the function so that save its data into a file? I can manually place the Kubo and do so as
PlayerHouse = Kubo.Name;
But what if I don't know which house I should save? Like instead of typing down
PlayerHouse = Apartment.Name;//2nd house
PlayerHouse = Modern.Name;//3rd house
Can I use an function argument to place the object's name into PlayerHouse? Like this
void SetHouseName(type object){
PlayerHouse = object.Name;
}
Few ways in which this can be done .. is keeping all created object in a container and then access access the container to get the object in and pass it a function which will write it to a file .
Also if you do not want to maintain the container what you have mentioned about using the function will also work fine
Of course, but if you are going to save the Name of the house anyway, why don't you just ask for a std::string in the first place and then pass the Name to that function?
void SetHouseName(std::string name)
{
PlayerHouse = name;
}
If this is outside your House class you need to create a method to expose the Name member of House though, or just make it public.
To answer your initial question, just as how you would pass built-in types, you can do the same for your House type :
void SetHouseName(House house)
{
PlayerHouse = house.Name;
}
I have spent a great deal of time in google trying to figure out how to pass a vector when using .h and .cpp files between a call in main and a function in an includes block. I was successful using class definitions.
Now everything is going fine until I want to create an overloaded function. (I could have done this with two different classes, but I must use one overloaded function in my program.)
Here is my writeData.h file:
#ifndef WRITEDATA_H
#define WRITEDATA_H
#include <vector>
#include <string>
#include <iostream>
#include <fstream>
using namespace std;
class writeData
{
public: writeData();
public: writeData(vector<int> & DATAFILE);
public: writeData(vector<int> & DATAFILE, string);
};
#endif
The placement of the using namespace std; is another topic.
Here is my writeData.cpp file:
#include "writeData.h"
writeData::writeData()
{
std::cout << "Default writeData" << std::endl;
}
writeData::writeData(vector<int> & DATAFILE)
{
cout << "writeData 1" << endl;
for (int var : DATAFILE)
{
cout << var <<endl;
}
}
writeData::writeData(vector<int> & DATAFILE, string fileName)
{
ofstream myfile(fileName);
cout << "writeData" << endl;
if (myfile.is_open())
{
for (int var : DATAFILE)
{
cout << var << endl;
myfile << var << endl;
}
myfile.close();
}
}
And here is my main function:
#include <iostream>
#include <vector>
#include <string>
#include "writeData.h"
using namespace std;
int main()
{
string fileName = "test.txt";
vector<int> items{ 10, 14, 22, 34 };
writeData();//default
///////////////////////////////////////////////////
// the next line is the problem code:
//writeData(items);//writes to screen only
//<<When I uncomment it the compiler Tosses the following:
// 'items': redefinition; different basic types
////////////////////////////////////////////////////
writeData(items, fileName);//writes to screen and to file
cin.ignore();
cin.get();
}
The offending line is writeData(items);
Any assistance or pointers to online articles would be most appreciated.
The immediate issue is that this declaration
writeData(items);
is the same as
writeData items;
hence the redefinition error. The deeper issue is that you have defined three constructors for a class, and seem to be attempting to call them without making a named instance. To succesfully call the one parameter constructor passing items, you'd need something like
writeData data_writer(items);
Alternatively, you may want either member functions, or non-members. The choice would depend on whether you really want to model a class, which maintains certain invariants or not. An example of members,
class writeData
{
public:
void write_data() const;
void write_data(const vector<int> & DATAFILE) const;
void write_data(const vector<int> & DATAFILE, string) const;
};
Then
WriteData wd;
wd.write_data(items);
Example of non-members:
namespace writeData
{
void write_data();
void write_data(const vector<int> & DATAFILE);
void write_data(const vector<int> & DATAFILE, string);
};
Then
writeData::write_data(items);
Note I have made the vector<int> parameters const reference because they are not being moified in the functions.