My constructor is suppose to only take one variable. But I'm curious if you ca initialize other variables that arent in the constructor defintion.
class WordAnalysis{
private:
int timesDoubled;
word *words;
int wordCount;
int index;
void doubleArrayAndAdd(string);
bool checkIfCommonWord(string);
void sortData();
public:
bool readDataFile(char*); //returns an error if file not opened
int getWordCount();
int getUniqueWordCount();
int getArrayDoubling();
void printCommonWords(int);
void printResult(int);
WordAnalysis(int);
~WordAnalysis();
};
Example: Would any instance of WordAnalysis now have timesdoubled as 0. and would a getter function be able to get this information without a setter?
WordAnalysis::WordAnalysis(int arrSize){
wordCount = arrSize;
int timesDoubled = 0;
int index = 0;
}
Well yes, you can initialize other member variables in the constructor,
even if it doesn't take the corresponding arguments.
However, in the example you gave above:
WordAnalysis::WordAnalysis(int arrSize){
wordCount = arrSize;
int timesDoubled = 0;
int index = 0;
}
You aren't actually initializing the timesDoubled member variables, because you wrote "int" before it, which is declaring a new variable and setting that to 0.
If you want to set the classes timesDoubled variable you have to write:
timesDoubled = 0;
Or if you want to be more explicit about it, you can even write:
WordAnalysis::timesDoubled = 0;
Yes. You can. But, you can do in-class initialization of your data members on declaration. You should use initializer list with constructor to initialize your required data members. All the data members are visible inside the constructor. You can assign their values in it. Technically, using initializer list is initialization and inside the ctor it is assignment when the assignment operator (=) is used.
Here's is the snippet of your code with comments:
class WordAnalysis
{
private:
// Data member initialization on declaration
int timesDoubled { 0 };
word* words { nullptr };
int wordCount { 0 };
int index { 0 };
public:
// Initializing timesDoubled using initializer list
WordAnalysis( const int t ) : timesDoubled{ t }
{
// Assign default values here if need be
index = 10; // assignment
}
// ...
};
Your compiler should be at least C++11 compliant to allow the in-class initializations of data members.
I suggest defining a default constructor such as:
WordAnalysis()
{
timesDoubled = 0;
words[0] = '\0'; //assuming it's an array of char
wordCount = 0;
index = 0;
}
That way all instances of the class would be initialized.
Related
How to initialize the array-like member variable?
The visual studio code says:
no matching function for call to 'Node::Node()' gcc line 12 col 9
const int N = 100;
struct Node {
int val, ch[2];
/**
void init(int _val) {
this->val = _val, this->ch[0] = this->ch[1] = 0;
}*/
Node (int _val): val(_val) {
this->ch[0] = this->ch[1] = 0;
}
} tree[N]; // <--------- this is line 12
int main() {
int a;
cin >> a;
tree[0] = Node(a);
}
The problem is that when you wrote tree[N] you're creating an array whose elements will be default constructed but since there is no default constructor for your class Node, we get the mentioned error.
Also, Node doesn't have a default constructor because you've provided a converting constructor Node::Node(int) so that the compiler will not automatically synthesize the default ctor Note::Node().
To solve this you can add a default ctor Node::Node() for your class.
I have this class:
class CContact {
public:
CTimeStamp m_Stamp;
int m_Num1;
int m_Num2;
CContact(CTimeStamp mStamp, int i, int i1) {
m_Stamp = mStamp;
m_Num1 = i;
m_Num2 = i1;
}
};
I get the following error:
Constructor for 'CContact' must explicitly initialize the member 'm_Stamp' which does not have a default constructor
I want to be able to use it this way:
test.addContact(CContact(CTimeStamp(1, 2, 3, 4, 5, 6), 999999999, 777777777));
What does it mean, and how can I fix it?
The error is self-explantory. Your CContact constructor is not passing any values to m_Stamp's constructor, so the compiler has to default-construct m_Stamp, but it can't because CTimeStamp does not have a default constructor.
You need to initialize CContact's members (or at least m_Stamp) in the CContact constructor's member initialization list rather than in the constructor's body, eg:
CContact(CTimeStamp mStamp, int i, int i1) :
m_Stamp(mStamp),
m_Num1(i),
m_Num2(i1)
{
}
This will invoke the copy constructor for m_Stamp rather than the default constructor.
You original code was effective equivalent to this, which is why it failed:
CContact(CTimeStamp mStamp, int i, int i1)
: m_Stamp() // <-- here
{
m_Stamp = mStamp;
m_Num1 = i;
m_Num2 = i1;
}
You have to define a default constructor for class CTimeStamp. For example:
CTimeStamp(int aa=0, int bb=0, int cc=0)
:a{aa},b{bb},c{cc}{}
class Graph {
private:
int n;
Head* array;
Graph(int n)
{
this->n = n;
array = new Head[n];
for (int i = 0; i < n; i++)
{
array[i].head->vertex = i;
}
}
};
When the first Head* array is being declared, it is being done in the stack. Then again it is being allocated to the heap using the new keyword inside the constructor.
I want to understand if this is the same as if we wrote: Head* array = new Head[n]; And if so then is this a standard way of declaring member variables in a class? Is it also because when objects are created constructors are invoked first, so member variables are not set if they are not in the constructor?
I mean: I've a bunch of various structures/classes and all this a splendor shall be initialized with known in advance values. Those structures/classes will never be used other way except the preinitialized one, so there is no any need for constructor -- it's just a waste of extra memory, extra CPU cycles in program, and extra space in source code.
If you have access to a C++11 compiler, you can mark your constructors as constexpr to have them run at compile time. The benefit of this is that way down the road you can still construct your objects at runtime. e.g.
struct Point2D {
constexpr Point2D(int x, int y) : x_{x}, y_{y} {}
int x_, y_;
};
And now you can use Point2D's constructor to initialize it at compile time, instead of runtime:
Point2D p{3, 4}; // no runtime overhead.
Structures and classes can be initialized, in limited circumstances.
struct splendor {
int i, j;
char *name;
};
splendor iforus = { 1, 2, "Extra!" };
Additionally, if you never need the name of the type of the structure:
struct {
int k;
float q;
} anon_e_mouse = { 1, 2.3 };
You can just initialize the members at the point of declaration:
struct Foo
{
int i = 42;
double x = 3.1416;
std::string name = "John Doe";
};
This will set up the default values for all instances:
Foo f;
std::cout << f.i << std::endl; // prints 42
Note that this does not work with C++03, it requires C++11 support.
If a class (or struct) doesn't have a constructor, you can initialize it like so:
MyClass a = MyClass();
or
MyClass * b = new MyClass();
This is called value initialization and it usually amounts to zero-initialization.
C++11 gives you initializer_list.
#include <iostream>
struct s
{
int i;
};
int main() {
s s1={666};
s s2={42};
std::cout<<s1.i<<" "<<s2.i<<std::endl;
return 0;
}
You can also do in-class initialization for member.
#include <iostream>
struct s
{
int i=0;
};
int main() {
s s1; //s1.i = 0
//s s2={42}; //fails
std::cout<<s1.i<<" "<<std::endl;
return 0;
}
But you cant do bot at the same time.
It sounds like you are trying to implement the Singleton Pattern. When you do that, you still need a constructor (in fact, if you want to force it to be a singleton, you have to declare the default constructor as private).
class MySingleton
{
private:
// my data
MySingleton() { /* initialize my data */ }
public:
static MySingleton& GetInstance()
{
static MySingleton instance;
return instance;
}
// other functions
};
I need to create a vector of vectors full of integers. However, I continuously get the errors:
error: expected identifier before numeric constant
error: expected ',' or '...' before numeric constant
using namespace std;
class Grid {
public:
Grid();
void display_grid();
void output_grid();
private:
vector<int> row(5, 0);
vector<vector<int> > puzzle(9, row);
int rows_;
int columns_;
};
You cannot initialize the member variables at the point where you declare them. Use an initialization list in the constructor for that:
Grid::Grid()
: row(5,0), puzzle(9, row),
rows_(5), columns_(9)
{
}
C++ class definitions are limited in that you cannot initialise members in-line where you declare them. It's a shame, but it's being fixed to some extent in C++0x.
Anyway, you can still provide constructor parameters with the ctor-initializer syntax. You may not have seen it before, but:
struct T {
T() : x(42) {
// ...
}
int x;
};
is how you initialise a member, when you might have previously tried (and failed) with int x = 42;.
So:
class Grid {
public:
Grid();
void display_grid();
void output_grid();
private:
vector<int> row;
vector<vector<int> > puzzle;
int rows_;
int columns_;
};
Grid::Grid()
: row(5, 0)
, puzzle(9, row)
{
// ...
};
Hope that helps.
You can't initialize a member in a class declaration unless it's const static, because in C++ no code is being run/generated when you are declaring a class. You'll have to initialize them in your constructor.
You should initialize members in the class constructor, not the declaration. The following doesn't seem to be right in any way:
vector<int> row(5, 0);
vector<vector<int> > puzzle(9, row);
If row and puzzle are functions - the parameters should be types. If they're member variables - initialize them in the class constructor.
You cannot initialize mutable members as a part of class definition itself. Instead do assign it in in the constructor.
// ....
Grid()
{
row.resize(5,0) ;
puzzle.resize(9,row) ;
}
private:
vector<int> row;
vector<vector<int> > puzzle ;
// ..