Declare a global variable without initialising in c++ - c++

Say I have a header file:
class.h
#pragma once
#include <iostream>
#include <string>
using namespace std;
class my_class
{
private:
string var1;
public:
my_class(string var1_val) { var1 = var1_val; };
};
I wish to declare a my_class variable as a global so it can be used across functions. However, it cannot be initialised outside the main function, as it requires user input to initialise. This poses a problem, as if the below code is run, I get: 'my_class': no appropriate default constructor available
source.cpp
#include <iostream>
#include <string>
#include "classes.h"
using namespace std;
my_class f;
int main(){
string inpt;
cout << "Enter var1 value: ";
cin >> inpt;
f = my_class(inpt);
}
How would I define the variable f so I could initialise it in main, but also use it in another function in the source.cpp file?

There are a few things mixed in the question. I'll try to address them individually.
The error message about the default constructor is exactly that: you are asking to instantiate an instance of that class but you only provide one way of doing so: the constructor with a string parameter.
Two ways you can deal with that "directly":
provide a default constructor, by either having it explicitly or making the string parameter optional, like my_class(string var1_val = {})
provide the said parameter at a time of instantiation: my_class f{""};
Have a variable "outside" in the global scope but initialized in main()... Also, a few ways to deal with that (personally I would advise against such a practice for various reasons, but providing options here for completeness):
Use pointers. Declare your variable as my_class * f{nullptr}; or, even better, as a smart pointer: std::unique_ptr<my_class> f; and instantiate the object in your main as either a naked pointer f = new my_class("string"); or a smart pointer f = std::make_unique<my_class>("args");
have that variable local to main() and pass it into whatever function you need it in
You might also look into using a Singleton Pattern where you have a factory function that manages your f (again, a horrible idea in this case, but providing it for completeness):
my_class & get_my_class(string s = {}){
static my_class * mc{nullptr};
if(!mc){ mc = new my_class{s}; } // <-- memory leak here unless you use unique_ptr
return *mc;
}
int main(){
// ...
auto & m{get_my_class("user input")};
// ...
}
void other_function(){
auto & f{get_my_class()};
// use f
}

The problem that you describe
as if the below code is run, I get: 'my_class': no appropriate default constructor available
is because you have declare another constructor with some parameter. In this case, compiler will not generate default constructor. You have to do it by yourself. so the class should look like:
class my_class
{
private:
string var1;
public:
my_class(){};
explicit my_class(string var1_val) :
var1(var1_val)
{};
};
Good practice is when you are making constructor with one argument mark it as explicit. Another good practice is to assign variables in constructor initialization list.
Best Regards

Just do this
my_class(string var1_val="") { var1 = var1_val; };
Provide default argument & you are good to go.
Just to get the compiler to shut up.
Although using global object is not a good solution.

That is not directly possible... a global class instance requires initialization (only types like int or double can be left initialized, but only in local scopes - as global they're always initialized - and this possibility of leaving variables uninitialized is also something many think is a design error of the C++ language - most younger languages do not provide this option as experience taught us that it's a source of nasty bugs and provides no real advantage).
What you want to do could be interpreted as a variation on what is normally called the "singleton pattern" ... i.e. providing all the modules access to a single instance of a class.
This in C++ is normally done using a function that returns a reference to the variable... for example:
------------------------------------------------------------ parms.h
...
struct Parms {
std::string user_name;
int user_age;
static Parms& get(); // Providing access to the singleton
};
-------------------------------------------------------- module1.cpp
#include "parms.h"
...
void foo() {
// access the singleton
std::cout << "Hello " << Parms::get().user_name << "\n";
}
---------------------------------------------------------- parms.cpp
#include "parms.h"
...
static Parms* parmsp;
void init_parms(const std::string& user_name, int user_age) {
// creates the singleton
parmsp = new Parms{user_name, user_age};
}
Parms& Parms::get() {
// Provide access to the singleton
if (!parmsp) {
throw std::runtime_error("Parameters not yet initialized");
}
return *parmsp;
}

Related

Using a class and functions to keep track of user stats

I am new to C++, and was wondering what I am doing wrong.
I am trying to create a text-based adventure game that keeps track of player stats using an add or remove function. Currently, my function does not add five points to trust and I am trying to get it to.
#include "function.h"
using namespace std;
int main() {
double trust=100;
editPlayer user(100);
//asks user choice
cin >> firstChoice;
if (firstChoice == 1) {
user.addTrust(trust);
cout << trust;
Here is my function.cpp only using trust as an example:
#include "function.h"
editPlayer::editPlayer(double trust) {
}
void editPlayer::addTrust(double trust){
trust +=5;
}
void editPlayer::removeTrust(double trust){
trust -=5;
}
And here is my function.h:
#include<iostream>
#include<string>
using namespace std;
class editPlayer{
public:
editPlayer(double trust);
void addTrust(double);
void removeTrust(double);
};
Lets take your addTrust function:
void editPlayer::addTrust(double trust) {
trust += 5;
}
This will modify the local variable trust, and then the function will end. When the function ends, the life-time of the local variable trust also ends, and the modifications you made to it will be lost.
If you truly want to modify the argument, you need to either pass it by reference:
void editPlayer::addTrust(double& trust) {
trust += 5;
}
Or return the new value:
double editPlayer::addTrust(double trust) {
return trust + 5;
}
If you return the new value, you need to assign to it when calling the function:
trust = user.addTrust(trust);
With the above said, the code and the editPlayer class doesn't make much sense. There's just no need for a class editUser really. Possibly addTrust could be a non-member function, or maybe not a function at all.
The class name doesn't make sense, since it doesn't "edit" anything. And passing an argument to the constructor also doesn't make sense since the objects doesn't have any internal state (the value passed to the constructor is just discarded).
Currently you're not storing anything specific on behalf of user object (an object of the editPlayer class.
The cout << trust; statement just prints a value of the trust local variable which you declared at the beginning: double trust=100;. Because this variable hasn't been changed anyhow since that initialization it is still equal to 100 and this is what you see.
In order to track any editPlayer-specific information the best idea is to store that information as a data member of the class editPlayer. You can declare a data member representing the trust of an object like this:
class editPlayer{
public:
editPlayer(double trust);
void addTrust(double);
void removeTrust(double);
double getTrust() const; // add also this one, will be useful
private:
double m_trust {0}; // <---- here - a data member, aka. a class field
};
Now you must refine you constructor to let it utilize the parameter which it takes and assign its value to this new data member (because currently the constructor does nothing):
editPlayer::editPlayer(double trust) {
m_trust = trust;
}
Now in the member functions that you already have just rename the variable so that it reflects the trust data member (and not the parameter) which effectively will allow to update its value:
void editPlayer::addTrust(double trust) {
m_trust += 5;
}
void editPlayer::removeTrust(double trust) {
m_trust -= 5;
}
double editPlayer::getTrust() const { // add definition of our "getter"
return m_trust;
}
Finally you can replace that cout << trust; which we already discussed (still prints the local variable's value) with an invokation of the getter which yields m_trust's value:
cout << user.getTrust();
and see the actual effect of performing the addTrust() operation as well as get delighted with your legitimate object-oriented program.
In general the code you are asking can be covered by classes, member declarations and also a pinch of object oriented programming.
The internet has lots of good (and less than good) tutorials if you search for it.
I would try my luck with some of the following searches
CPP + classes
CPP + member declarations
CPP + dynamic vs. static memory allocation (pointers and stuff)
object oriented programming (OOP)
The examples on this site provide good (and short :D) examples of alot of basic concepts imho.
https://www.tutorialspoint.com/cplusplus/cpp_classes_objects.htm
Some of the topics also apply to other languages.
The first block with my comments:
#include "function.h"
using namespace std; // dont get into the habbit of using namespace std;
// the above can potentially open up for bugs
int main()
{
double trust=100; // This variable is declared in this scope({ ... })
// and will get deallocated once the scope ends with the character '}'
editPlayer user(100); // instance of editPlayer named 'user' is constructed
//asks user choice
cin >> firstChoice;
if (firstChoice == 1) {
user.addTrust(trust); // calling function on user object
cout << trust;
}
Now looking at the .h file i would advocate against including headers that you dont use in the header.
For small projects it does not matter at all - but for big projects of thousands lines of code removing unused includes can speed up things.
Some would prefer forward declarations - which you can look into once you are more comfortable with the basics of cpp.
#include<iostream> // not used here
#include<string> // not used
using namespace std; // disaster waiting to happen
class editPlayer{
public:
editPlayer(double trust);
void addTrust(double);
void removeTrust(double);
};
The .cpp file
#include "function.h"
editPlayer::editPlayer(double trust) {}
// function implementation with argument - but argument is not used - change to void fun(double) -> fun(void) OR fun()
void editPlayer::addTrust(double trust) { trust +=5; }
void editPlayer::removeTrust(double trust) { trust -=5; }
I did an example with class declaration and member variables.
#include <iostream>
#include <string>
// this is a class declaration
class Player
{
protected: // protected member variables
double _trust;
public: // public interface
Player(double trust);
void addTrust(double);
void removeTrust(double);
double getTrust() const;
};
// Implementation of public interface
// notice _trust is the member defined in the class
Player::Player(double trust) : _trust(trust) {} // constructor
// example of default parameters (do note that only definition or declaration can have them)
// This means that calling the function without arguments will become 5
void Player::addTrust(double trust = 5) { _trust += trust; }
void Player::removeTrust(double trust = 5) { _trust -= trust; }
double Player::getTrust() const {return _trust; }
int main()
{
Player player(100); // this will invoke the constructor - and the player object will get initialised with the given state
std::cout << player.getTrust() << std::endl;
// variable to buffer input data into - assuming type int wrt. following if
int firstChoice;
//asks user choice
std::cin >> firstChoice;
if (firstChoice == 1)
{
player.addTrust(25);
player.addTrust();
}
std::cout << player.getTrust();
}
Happy coding !

Why does my class std::vector member always throw a segfault?

I've searched endlessly on SE for a logical explanation for why this is happening. It is probably something very simple that I've overlooked, however I cannot spot it and would really appreciate some assistance with this.
Last week I implemented a class to read the output of a system call from a .ini file and then find and store the required information into custom objects that are then stored in a vector inside a Config class. It is a Singleton config class storing a unique_ptr for each instance of my custom class that is created.
The thing is, when I implemented this last week on my laptop, I had zero issues reading and writing to my member vector and was able to get it working exactly how I needed it. Since pulling to my desktop computer, this vector, and any STL container that I use as a member of my class, throws a segmentation fault when I try to do anything on it, even get it's size.
I've tried to shorten the code below to only include sections that actually use this vector. I have replaced my config with A, and custom class with T, and no matter where I try to use my member container, or any other test STL containers that I add to the class, I get a segfault.
For the record, I am using Qt with C++11.
Update: This example breaks on line 50 of c.cpp when debugging, and anywhere that tries to call the vector.
Debug points to this line in stl_vector.h
// [23.2.4.2] capacity
/** Returns the number of elements in the %vector. */
size_type
size() const _GLIBCXX_NOEXCEPT
/*-> this line */ { return size_type(this->_M_impl._M_finish - this->_M_impl._M_start); }
main.cpp
#include "c.h"
int main(int argc, char *argv[])
{
C *c = C::getInstance();
delete c;
return 0;
}
t.h - Class stores information from file
#include <string>
class T
{
public:
T();
bool Active();
std::string getA();
void setA(std::string);
private:
std::string a;
};
t.cpp
#include "t.h"
T::T()
{
}
bool T::Active()
{
if(a == "")
{
return false;
}
return true;
}
std::string T::getA()
{
return this->a;
}
void T::setA(std::string newa)
{
this->a = newa;
}
c.h - Class stores T objects and parses file for information
#include "t.h"
#include <QDebug>
#include <vector>
#include <algorithm>
#include <iostream>
#include <memory>
#include <sstream>
#include <fstream>
class C
{
public:
static C* getInstance();
private:
C();
static C* instance;
static bool init;
std::vector<std::unique_ptr<T>> t_list;
void readLines(const std::string&);
};
c.cpp
#include "c.h"
bool C::init = false;
C* C::instance = nullptr;
C::C()
{
system("echo this is a test command > a.ini");
instance->readLines("a.ini");
}
C* C::getInstance()
{
if(!init)
{
instance = new C;
init = true;
}
return instance;
}
void C::readLines(const std::string &path)
{
T* new_t;
std::ifstream file(path.c_str());
if(!file.is_open())
{
qDebug() << "Unable to open " << path.c_str();
}
std::ofstream o("test.txt");
std::string line;
while(std::getline(file, line))
{
// Split string before searching
std::stringstream ss(line);
std::string seg;
std::vector<std::string> split;
std::string left, right;
// Search patterns
size_t find_a = line.find("a");
size_t del = line.find(':');
if(find_a != std::string::npos)
{
o << "test_Size: " << t_list.size() << std::endl;
if(new_t->Active())
{
T* temp = new_t;
std::unique_ptr<T> move_t(temp);
t_list.push_back(std::move(move_t));
}
o << "test: " << t_list.size() << std::endl;
std::string n;
// Check if previous ahas any null elements
// Split string to find a
n = line.substr(line.find("a "));
n = n.substr(n.find(" ", +2));
new_t->setA(n);
}
else
{
continue;
}
}
// Add last a
T* t = new_t;
std::unique_ptr<T> move_t(t);
//t_list.push_back(std::move(move_t));
o << "a: " << t_list.back().get()->getA() << std::endl;
o << t_list.size() << std::endl;
o.close();
file.close();
}
UPDATE after code change:
I see two things now: One is that new_t in C::readlines is never initialized, so this could break when new_t->Active() is called a bit later in the function. However, I believe that the main problem you're running into is in C::C(), where it says
instance->readLines("a.ini");
At this point in the execution, C::instance is not yet initialized -- you're only just constructing the object that would later be assigned to it. Because of this, this in the readlines call is invalid, and any attempt to access object members will cause UB. This latter problem can be fixed by just calling
readLines("a.ini");
in which case the currently constructed object (that will later be instance) is used for this. I have no idea what you want to happen for the first, though, so all I can say is: If you want to have a vector<unique_ptr<T>>, you will have to create objects of type T with either new T() or (arguably preferrably) std::make_unique<T>() and put them in there.
I'll also say that this is a rather ugly way to implement a singleton in C++. I mean, singletons are never really pretty, but if you're going to do it in C++, the usual way is something like the accepted answer of C++ Singleton design pattern .
Old answer:
The problem (if it is the only one, which I cannot verify because you didn't provide an MCVE) is in the lines
T move_t = new_T;
std::unique_ptr<Adapter> ptr_t(&move_t); // <-- particularly this one
m_ts.push_back(std::move(ptr_t));
You're passing a pointer to a local object into a std::unique_ptr, but the whole purpose of std::unique_ptr is to handle objects allocated with new to avoid memory leaks. Not only will the pointer you pass into it be invalid once the scope surrounding this declaration is left, even if that weren't the case the unique_ptr would attempt to delete an object that's not on the heap at the end of its lifecycle. Both problems cause undefined behavior.
To me, it looks as though you really want to use a std::vector<T> instead of std::vector<std::unique_ptr<T>>, but that's a design issue you'll have to answer yourself.
Answering my own question here. I am trying to call a member variable from within the constructor of the object that holds it, so the vector I am trying to access is not yet instantiated and doesn't exist in memory. That is what causes the Segmentation fault to occur, I am trying to access memory that is not allocated yet, hence any call acting on any member of my C class was causing this issue.
I fixed this problem by adding a public function to the class that then calls the private readLines() function. I call that public function from the object that will take ownership of it, and since this occurs after it has been instantiated, the memory is accessible and the problem disappears.

why does "ClassType Object;" equals to "ClassType(Object);" in C++?

in first, want to start to mention that it could be sorry for my bad english.
in C++, when we want to create a instance of certain type of class, we usually use "ClassType ObjectName;"
for example,
class Foo {};
Foo instance1;
but, i've met some codes make me embarassment a little. it following next.
class A {/*....bla bla*/};
class B {
public:
B(char*) {}
};
void main() {
A aaa;
B(aaa); // this makes a error.
}
by trial and error, i could know that "B(aaa);" is exactly same to "B aaa;".
But why? is this a kind of what depicted on standard documents? if so, please let me know where i can see.
Thanks in advance.
UPDATE:
Thank you for your all replies.
But i think that i've omitted some codes. Sorry.
#include <iostream>
using namespace std;
class A
{
};
class B
{
public:
B() { cout << "null\n"; }
B(char* str) {}
void print() {
cout << "print!\n";
}
};
void main()
{
A aaa;
//B(aaa); this line makes a error that says 'redefinition; different basic types'. VS2008
B(aa1);
aa1.print();
}
Output:
null
print!
as you can see, "B(aa1)" statement means not to pass aa1 to constructor as argument, but to create a instance aa1.
Until now, I've known "B(argument)" to "Pass argument to propel one of a overloaded construtor, and create a nameless temporary instance".
but value "aa1" looks lke neither a defined value nor a temporary instance.
Sometimes a set of parenthesis is needed to disambiguate declarations.
For example:
int *f(); // a function returning a pointer to int
int (*f)(); // a pointer to a function returning an int
Rather than listing exactly when and where using parenthesis is required and where it perhaps should be forbidden (because it is useless), the standard just says that they are allowed.
So you end up with the slightly confusing:
int a; // an int variable
int (b); // another int variable

Why/When would I want to use a class data member without defining an object of the class?

It is possible in C++ to use a data member of a class without defining an object of that class, by defining that data member in the public section as a static variable, as in the code sample below. The question is, why/when would I want to do this? and how can I do it?
class ttime{
public:
ttime(int h=0, int m=0, int s=0):hour(h), minute(m), second(s){} //constructor with default intialization
int& warning(){return hour;}
void display()const{cout<<hour<<"\t";}
static int hello;
~ttime(){}
private:
int hour;
int minute;
int second;
};
main()
{
ttime:: hello=11310; //Is this the way to use hello without creating an object of the class?
cout << ttime:: hello;
ttime hi(9);
hi.display();
hi.warning()++;//the user is able to modify your class's private data, which is really bad! You should not be doing this!
hi.display();
}
Declaring a class member variable as static essentially makes it a singleton object that is shared by all of the instances of that class. This is useful for things like counters, semaphores and locks, and other types of data that need to be shared by the other class members.
Declaring it public makes it accessible to all users of that class. It's generally a bad idea to allow class variables to be modifiable by functions outside the class, though.
Declaring it const, on the other hand, is the usual way to provide publicly readable constants for the class.
Example
Your library class:
class Foo
{
public:
// Version number of this code
static const int VERSION = 1;
private:
// Counts the number of active Foo objects
static int counter = 0;
public:
// Constructor
Foo()
{
counter++; // Bump the instance counter
...
}
// Destructor
~Foo()
{
counter--; // Adjust the counter
...
}
};
Some client of your library:
class Bar
{
public:
// Constructor
Bar()
{
// Check the Foo library version
if (Foo::VERSION > 1)
std::cerr << "Wrong version of class Foo, need version 1";
...
}
};
In this example, VERSION is a static constant of the class, which in this case informs the outside world what version of the code is contained in the class. It's accessed by the syntax Foo::VERSION.
The static counter variable, on the other hand, is private to the class, so only member functions of Foo can access it. In this case, it's being used as a counter for the number of active Foo objects.
As cited before, static member variables work as 'global' variables, but within the class namespace.
So it is useful for counters or shared resources between objects.
In the case of 'public static' modifier, it is easy to see its use within libraries to provide access to constants and general-purpose functionality (static methods).
For example, an input library might have:
class KeyEvent
{
public:
static const int KEY_DOWN = 111;
static const int KEY_UP = 112;
...
}
//And then in your code
#include <KeyEvent>
void poolEvent(Key *key)
{
if(key->type() == KeyEvent::KEY_DOWN)
...
}
I am not familiar with the c++ syntax for statics at the moment. But in c++-cli (.net, Visual C++) the :: is correct.
For the purpose of statics:
There are many cases where it makes sense to use them. In general, when you want to store information that belong to the class itself (meaning to all objects of the class) and not to a single object/instance.
Even though not originally invented for this purpose, static constexpr data members of structs are a backbone of template meta-programming. Just check out the limits standard library header as a simple example.
For example, we can define a wrapper around the builtin sizeof operator. While rather useless in itself, it hopefully gives the right idea.
#include <iostream>
template<typename T>
struct Calipers
{
static constexpr auto size = sizeof(T);
};
int
main()
{
std::cout << "short: " << Calipers<short>::size << "\n";
std::cout << "int: " << Calipers<int>::size << "\n";
std::cout << "long: " << Calipers<long>::size << "\n";
std::cout << "float: " << Calipers<float>::size << "\n";
std::cout << "double: " << Calipers<double>::size << "\n";
}
Possible output:
short: 2
int: 4
long: 8
float: 4
double: 8
It is similar to a global variable, only that it is not defined at the global namespace.
You find it in C++ code that was written before namespaces were introduced, or in template meta programming were it is more useful.
In general, I would not recommend to use it as in your example and would prefer to avoid global state as much as possible. Otherwise, you end up with code that is difficult to test.

Another way to refer members in a structure

Now, I am learning as to how to use structures properly in C++.
Is there another way to refer members in a structure.
As an example, below is my code.
I want to know if I can do something like test.b to refer name member in the structure.
Is there any incredible way to do so?
#include <iostream>
using namespace std;
struct A
{
string name = "Test";
};
int main()
{
A test;
string b = "name";
cout << test.name;
return 0;
}
If you don't need to use a string to reference the member then the way to do this is called "pointer to member":
struct A
{
int name;
int value;
};
main()
{
int A::* b = &A::name; // assign "name" to the variable called b
struct A test = {1,2}; // make a structure and fill it in
return test.*b; // use the variable called b to reference test.name
}
If you do need to refennce the items with a string the other way mentioned in the contents is to use a map. That can be useful if all your members are the same type.
#include <iostream>
#include <map>
main()
{
std::map<std::string,int> test; // make something that can be keyed by a string
test["name"]=1; // put something called "name" in the map with a value of 1
test["value"]=2; // put something called "value" in the map with a value of 2
std::cout << test["name"] << std::endl;
return 0;
}
What you are referring to is called Reflection (function/attribute access by name). C++ by default doesn't have reflection. So probably you need to look for libraries/frameworks for that. Google "C++ Reflection" for that. Boost is one of the solution out there for C++ reflection/serialization.