How to initialize the array-like member variable in the constructor? - c++

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.

Related

Constructor with an object as argument (C++)

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}{}

How to do constructor for 2D vector in C++?

I tried initializing a 2D vector with a constructor in 3 different ways but always get an
"error: no matching function to call"
Could you tell me where I am wrong?
class Node
{
public:
int to;
int length;
Node(int to, int length) : to(to), length(length){}
};
class Graph
{
public:
vector<vector<Node>> nodes_list;
int n;
Graph();
};
Graph::Graph(){
nodes_list = vector<vector<Node> >(n, vector<Node>(n,0x3fffffff));
}
vector<Node>(n,0x3fffffff);
is (roughly) equivalent to:
vector<Node> v;
for ( size_t i = 0; i < n; i++ )
{
v.push_back(Node(0x3fffffff));
}
As your Node class doesn't have a constructor taking a single integer this fails to compile. The correct code is:
vector<Node>(n,Node(0x3fffffff,0));
By the way I assume you have using namespace std; in your header for Graph, don't do that, it will cause you issues at some point.
Your code has two problems:
At the following line, you should have provided the parameters for
constructing the Node, which are to and legth.
vector<vector<Node>>(n, vector<Node>(n,0x3fffffff));
// ^^^^^^^^^^^--> here
In Graph, the member n is un-initialized, at the
point, you call the default constructor. That would lead you to have
a garbage value in n and hence the size of the nodes_list would
be undefined.
The fixed code will look like:
struct Node
{
int _to;
int _length;
Node(int to, int length) : _to{ to }, _length{ length } {}
};
class Graph
{
using VecNode = std::vector<Node>; // type alias for convenience
private:
int _n;
std::vector<VecNode> _nodes_list;
public:
Graph()
: _n{ 2 } // initialize _n
, _nodes_list{ _n, VecNode(_n, { 1, 3 }) }
// ^^^^^^-> initialize with the default 'Node(1, 3)'
{}
};
Also some suggestions:
Use member initializer
lists
to initialize the vector, instead of creating and assign to it.
It's not a good idea to name both constructor parameters and the
members with same in Node. At some point, that may lead to
confusions.

Constructor Initialization and private variables set inside constructor

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.

Copy constructor for 2d array c++

I have managed to overload the assignment operator, so I do have a workaround for this, but it would be nice to know why I couldn't get it working.
The beginning of my arr2d class looks like:
template <class type> class arr2d {
private:
type* m_ptr;
int m_nx,m_ny;
public:
arr2d(){
m_ptr = 0;
m_nx = 0;
m_ny = 0;
}
// Default constructor creates a null array
arr2d(int nx, int ny):m_nx(nx),m_ny(ny){
m_ptr = new type [nx*ny];
if ( m_ptr==0 ){cout << "\nError allocating heap memory.\n";}
}
// // Copy constructor
// arr2d(const arr2d& rhs){
// m_ptr = new type [m_nx*m_ny];
// for(int j=0;j<m_ny;j++){
// for(int i=0;i<m_nx;i++){
// m_ptr[j*m_nx+i] = rhs.m_ptr[j*m_nx+i];
// }
// }
// }
and so on,
You can see my attempted copy constructor commented out there.
Now in my main, I would like to call the copy constructor using for instance:
arr2d b=a;
Where the b array now has the same values as a. What am I doing incorrectly?
You copy constructor is not assigning the array size. It should be something like
arr2d(const arr2d& rhs) : m_nx(rhs.m_nx), m_ny(rhs.m_ny) {
...
}
In addition to initializing m_nx and m_ny as 6502 said, you still need the template argument when declaring b. E.g.
arr2d<int> b = a;

C++ struct constructor

I tried to create my own structure. So I wrote this piece of code.
struct node
{
int val, id;
node(int init_val, int init_id)
{
val = init_val;
id = init_id;
}
};
node t[100];
int main()
{
...
}
I tried to compile my program. But I got an error:
error: no matching function for call to 'node::node()'
note: candidates are:
note: node::node(int, int)
note: candidate expects 2 arguments, 0 provided
note: node::node(const node&)
note: candidate expects 1 argument, 0 provided
node t[100];
will try to initialise the array by calling a default constructor for node. You could either provide a default constructor
node()
{
val = 0;
id = 0;
}
or, rather verbosely, initialise all 100 elements explicitly
node t[100] = {{0,0}, {2,5}, ...}; // repeat for 100 elements
or, since you're using C++, use std::vector instead, appending to it (using push_back) at runtime
std::vector<node> t;
This will fix your error.
struct node
{
int val, id;
node(){};
node(int init_val, int init_id)
{
val = init_val;
id = init_id;
}
};
You should declare default constructor.