class A
{
int id;
public:
A (int i) { id = i; }
void show() { cout << id << endl; }
};
int main()
{
A a[2];
a[0].show();
a[1].show();
return 0;
}
I get an error since there is no default constructor.However thats not my question.Is there a way that ı can send parameters when defining
A a[2];
A good practice is to declare your constructor explicit (unless it defines a conversion), especially if you have only one parameter. Than, you can create new objects and add them to your array, like this :
#include <iostream>
#include <string>
class A {
int id;
public:
explicit A (int i) { id = i; }
void show() { std::cout << id << std::endl; }
};
int main() {
A first(3);
A second(4);
A a[2] = {first, second};
a[0].show();
a[1].show();
return 0;
}
However, a better way is to use vectors (say in a week you want 4 objects in your array, or n object according to an input). You can do it like this:
#include <iostream>
#include <string>
#include <vector>
class A {
int id;
public:
explicit A (int i) { id = i; }
void show() { std::cout << id << std::endl; }
};
int main() {
std::vector<A> a;
int n = 0;
std::cin >> n;
for (int i = 0; i < n; i++) {
A temp(i); // or any other number you want your objects to initiate them.
a.push_back(temp);
a[i].show();
}
return 0;
}
Related
I have recently started working with shared pointers and need some help. I have a vector 1 of shared pointers to some objects. I need to construct another vector 2 of shared pointers to the same objects, so that modifying vector 2 would result in modification of vector 2.
This is how my code looks like:
This works fine
class A
{
public:
int a;
A (int x) {
a = x;
}
int print() {
return a;
}
};
int main()
{
shared_ptr<A> ab = make_shared<A>(100);
cout<< ab->print();
shared_ptr<vector<shared_ptr<A>>> vec1 = make_shared<vector<shared_ptr<A>>>(1);
shared_ptr<vector<shared_ptr<A>*>> vec2 = make_shared<vector<shared_ptr<A>*>>();
vec2->push_back(&(*vec1)[0]);
for (shared_ptr<A>* obj : *vec2) {
*obj = make_shared<A>(100);
}
cout << (*((*vec1)[0])).a; // Prints 100
return 0;
}
But this gives a SEGV at the last line since vec1 is not populated:
class A
{
public:
int a;
A (int x) {
a = x;
}
int print() {
return a;
}
};
int main()
{
shared_ptr<vector<shared_ptr<A>>> vec1 = make_shared<vector<shared_ptr<A>>>(1);
shared_ptr<vector<shared_ptr<A>>> vec2 = make_shared<vector<shared_ptr<A>>>();
vec2->push_back((*vec1)[0]);
for (shared_ptr<A> obj : *vec2) {
obj = make_shared<A>(100);
}
cout << (*((*vec1)[0])).a; // SIGSEGV
return 0;
}
I want to understand why vec1 was not populated in the 2nd one and also would like to know if there is any other way of doing this. Thanks!
The code for the setup described in the comments could be:
#include <vector>
#include <memory>
#include <iostream>
using namespace std;
struct A
{
int a;
A(int a): a(a) {}
};
int main()
{
auto p_vec1 = make_shared<vector<shared_ptr<A>>>();
auto p_vec2 = make_shared<vector<shared_ptr<A>>>();
for (int i = 0; i < 100; ++i)
p_vec1->push_back( make_shared<A>(i) );
for (int i = 0; i < 50; ++i)
p_vec2->push_back( (*p_vec1)[i * 2] );
(*p_vec1)[2]->a = 213;
std::cout << (*p_vec2)[1]->a << '\n'; // print 213
return 0;
}
In case you are unaware, the "outer" shared_ptr is unnecessary, you could just use two vectors .
I'm a beginner and was researching to find out if you can grab a name from an array to then put that name as the name of the object in a for loop.
The code a specifically created for this question is represented below:
#include <iostream>
using namespace std;
class YourMum{
public:
string name;
YourMum(string aName){
name = aName;
}
};
int main()
{
string names[5] = {"Jeremy_Clarkson", "Boris_Johnson", "Vladmir_Putin", "Peter_Griffin", "MeAndYourMum"};
for(int i = 0; i < 4; i++) {
YourMum names[i];
cout << names[i].name << endl;
cout << "You are great if you answer my question!";
}
return 0;
}
Okay, it's not clear what you're trying to do, but you've got a few things that aren't a good idea.
First, you defined string names[5] and then inside loop you hid names by making a second variable with the same name. While that's legal, it's a bad practice.
Second, you're using the second one (YourMum names) illegally:
You declared it as length i (using a non-standard feature of the compiler) but then reference element i. The elements of an array of length i range from 0..i-1, so [i] is one element past the end.
And you haven't initialized it anyway.
I'm not really clear what you're trying to do, so I can't even provide example code of how to do it.
The YourMum class you have shown is not default constructible, so YourMum names[size]; will not work. Every object of YourMum needs to be passed a parameter in order to create it. You can use placement-new for that, eg:
#include <iostream>
#include <type_traits>
using namespace std;
class YourMum{
public:
string name;
YourMum(string aName){
name = aName;
}
};
int main()
{
string names[5] = {"Jeremy_Clarkson", "Boris_Johnson", "Vladmir_Putin", "Peter_Griffin", "MeAndYourMum"};
std::aligned_storage<sizeof(YourMum), alignof(YourMum)>::type arr[5];
YourMum *mums = reinterpret_cast<YourMum*>(arr);
for(int i = 0; i < 5; i++) {
new (&mums[i]) YourMum(names[i]);
}
for(int i = 0; i < 5; i++) {
cout << mums[i].name << endl;
cout << "You are great if you answer my question!";
}
for(int i = 0; i < 5; i++) {
mums[i].~YourMum();
}
return 0;
}
Or, you can use std::vector instead:
#include <iostream>
#include <vector>
using namespace std;
class YourMum{
public:
string name;
YourMum(string aName){
name = aName;
}
};
int main()
{
string names[5] = {"Jeremy_Clarkson", "Boris_Johnson", "Vladmir_Putin", "Peter_Griffin", "MeAndYourMum"};
std::vector<YourMum> mums;
mums.reserve(5);
for(int i = 0; i < 5; i++) {
mums.emplace_back(names[i]);
}
for(int i = 0; i < 5; i++) {
cout << mums[i].name << endl;
cout << "You are great if you answer my question!";
}
return 0;
}
First of all, you should rename the name variable to something like _name or name_ for lisibility (to differenciate it from variables that aren't in the class), and you should also use the private section of your class to declare it and use getters/setters functions to edit it. Secondly, in your code you are declaring the object inside a loop, so it will get destroyed as soon as the loop iterates again, so if you want to create n objects in a loop and interact with them after you should either use a container class (like std::vector) or use a default constructor (which is better). Here is an updated version of your code:
#include <iostream>
#include <string>
class YourMum
{
public:
YourMum(void) : _name() { }
YourMum(std::string name) : _name(name) { }
std::string getName(void) const { return _name; }
void setName(std::string name) { _name = name; }
private:
std::string _name;
};
int main()
{
std::string names[5] = { "Jeremy_Clarkson", "Boris_Johnson", "Vladmir_Putin", "Peter_Griffin", "MeAndYourMum" };
YourMum mums[5];
for (int i = 0; i < 5; i++)
{
mums[i].setName(names[i]);
std::cout << mums[i].getName() << std::endl
<< "You are great if you answer my question!" << std::endl;
}
// this way you can still access mums here if you want to
return 0;
}
If you want to access to a class by it's name as index what you can also do is using std::map like this
#include <map>
int main()
{
std::string names[5] = { "Jeremy_Clarkson", "Boris_Johnson", "Vladmir_Putin", "Peter_Griffin", "MeAndYourMum" };
std::map <std::string, YourMum> mums;
for (int i = 0; i < 5; i++)
mums[names[i]] = YourMum(names[i]);
std::cout << mums["Jeremy_Clarkson"].getName() << std::endl;
return 0;
}
Try This
> for(int i = 0; i < 4; i++) {
> YourMum name(names[i]);
>
> cout << name.name << endl;
> cout << "You are great if you answer my question!";
> }
I need help... appropriate questions have been asked in the comments. The programs has zero compiler errors and warnings!! I have concerns with calling a member function from another member function using function pointers. (To be precise, setMatrixto() is trying to call setElement() function using function pointer)
Plus somehow the "hello there" is not being printed to the console. I was expecting it to show up as output.Maybe the setMatrixto() is not getting called at all!!
Header File definition
#ifndef MATRIXOPERATIONS_H
#define MATRIXOPERATIONS_H
class MatrixOperations;
typedef int (MatrixOperations::*INTFUNC)(int,int);
typedef void (MatrixOperations::*VOIDFUNC)(int,int,int);
class MatrixOperations
{
public:
MatrixOperations();
MatrixOperations(int size);
~MatrixOperations();
//diagonal matrix funtions
void displayMatrixOf(INTFUNC f);
void setMatrixTo(VOIDFUNC f);
int getElement(INTFUNC from, int i, int j);
void setElement(VOIDFUNC to,int i ,int j, int value);
int fromDiagonalArray(int i, int j);
void toDiagonalArray(int i, int j, int value);
protected:
private:
int size;
int* a;
};
#endif // MATRIXOPERATIONS_H
CPP Implementation File
#include "MatrixOperations.h"
#include <iostream>
using namespace std;
MatrixOperations::MatrixOperations()
{
//ctor
size = 3;
a = new int[size];
}
MatrixOperations::MatrixOperations(int size)
{
//ctor
this->size = size;
a = new int[size];
}
MatrixOperations::~MatrixOperations()
{
//dtor
delete[] a;
}
///////////////////FUCNTION POINTER SECTION///////////////////////////////////
int MatrixOperations::getElement(INTFUNC from, int i, int j)
{
return (this->*from)(i,j);
}
void MatrixOperations::setElement(VOIDFUNC to,int i ,int j, int value)
{
(this->*to)(i,j,value);
}
/////////////////////////////////DIAGONAL ARRAY OPERATIONS/////////////////////////////////////////////////
int MatrixOperations::fromDiagonalArray(int i, int j)
{
if(i==j)
{
return a[i];
}
else
{
return 0;
}
}
void MatrixOperations::toDiagonalArray(int i, int j, int value)
{
a[i] = value;
}
///////////////////////////////////////////////////////////////////
void MatrixOperations::displayMatrixOf(INTFUNC f)
{
for(int i{0}; i < size; i++)
{
for(int j{0}; j < size; j++)
{
cout << getElement(f,i,j) << "\t"; //is this the correct way to send the function pointer?
}
cout << endl;
}
}
void MatrixOperations::setMatrixTo(VOIDFUNC f)
{
cout << "Hello there!!"; //not getting this output.. whats wrong??
for(int i{0}; i < size; i++)
{
int value {};
cout << "Enter value diagonal element " << i << " : ";
cin >> value;
setElement(f,i,i,value); //is this the correct way to send the function pointer?
}
}
///////////////////////////////////////////////////////////////////////////////
Main File
#include <iostream>
#include "MatrixOperations.h"
typedef MatrixOperations MATRIX;
using namespace std;
int main()
{
MATRIX m1;
m1.setMatrixTo(MATRIX::toDiagonalArray); //was expecting a "Hello there!" but i am not getting that output either
return 0;
}
EDIT2: I added all the class definitions and main function in one single file. SURPRISINGLY!! this works . I am confused??!!!
#include <iostream>
using namespace std;
class MatrixOperations;
typedef void (MatrixOperations::*VOIDFUNC)(int,int,int);
typedef MatrixOperations MATRIX;
class MatrixOperations
{
public:
MatrixOperations();
MatrixOperations(int size);
~MatrixOperations();
//diagonal matrix funtions
void setMatrixTo(VOIDFUNC f);
void setElement(VOIDFUNC to,int i ,int j, int value);
void toDiagonalArray(int i, int j, int value);
private:
int size;
int* a;
};
MatrixOperations::MatrixOperations()
{ //ctor
size = 3;
a = new int[size];
}
MatrixOperations::MatrixOperations(int size)
{ //ctor
this->size = size;
a = new int[size];
}
MatrixOperations::~MatrixOperations()
{
//dtor
delete[] a;
}
void MatrixOperations::setElement(VOIDFUNC to,int i ,int j, int value)
{
(this->*to)(i,j,value);
}
/////////////////////////////////DIAGONAL ARRAY OPERATIONS/////////////////////////////////////////////////
void MatrixOperations::toDiagonalArray(int i, int j, int value)
{
a[i] = value;
}
///////////////////////////////////////////////////////////////////
void MatrixOperations::setMatrixTo(VOIDFUNC f)
{
cout << "Hello there!!" << endl;
for(int i{0}; i < size; i++)
{
int value {};
cout << "Enter value diagonal element " << i << " : ";
cin >> value;
setElement(f,i,i,value);
}
}
int main()
{
MATRIX m1;
m1.setMatrixTo(MATRIX::toDiagonalArray);
return 0;
}
There is nothing wrong with the code in both cases. Its just my debugger was not running in admin mode. I got error code 740. So I launched my IDE in admin mode and voila it worked.
In the class constructor, I am initializing other objects and pushing these objects to my class vector member. From what I understand, the vector create a copy of the object and stores it so that it doesn't go out of scope. However, when verifying the objects in another class function, they are not initialized anymore. Here's a example code to explain the behaviour:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
class Square {
private:
int size_ = 0;
int colour_ = 0;
public:
Square(){
size_ = 0;
colour_ = 0;
}
void init(int size, int colour) {
size_ = size;
colour_ = colour;
}
int get_size() { return size_; }
};
class SetSquares {
private:
std::vector<Square> squares_;
int number_;
public:
SetSquares(): number_(0) {}
void init(int num) {
number_ = num;
squares_.clear();
squares_.resize(num);
for (int i=0; i < num; i++) {
Square square;
square.init(i, i);
squares_.push_back(square);
}
}
void sample(int i) {
if (i >= number_) { return; }
std::cout << "Square size is: " << squares_[i].get_size() << std::endl;
}
};
int main()
{
SetSquares set_of_squares;
set_of_squares.init(7);
set_of_squares.sample(4);
return 0;
}
resize(n) will create n default constructed elements in a vector and push_back will append new elements after those n elements. Use reserve and push_back or resize and index operator as suggested in comment.
i am working on a worksheet i have for university and the question asks me to "Allow a user to enter 10 numbers from the keyboard into an array" however we have been told that we need to use classes and vectors for this task. When i run my code i get an error stating: "Expression: Vector subscript out of range"
can anyone help?
Array.h
#include <iostream>
#include <vector>
using namespace std;
class Array
{
private:
vector<int> lists;
public:
void fillArray();
void printForwards();
void halfandHalf();
void shiftArrayRight();
Array();
Array(vector<int>);
};
Array.cpp
#include "Array.h"
Array::Array()
{
lists[10];
}
Array::Array(vector<int> lists)
{
this->lists = lists;
}
void Array::fillArray()
{
for (int i = 0; i < 10; i++)
{
cin >> lists[i];
}
}
void Array::printForwards()
{
for (int i = 0; i < 10; i++)
{
cout << lists[i];
}
}
Source.cpp
#include <iostream>
#include "Array.h"
using namespace std;
int main()
{
Array list1,list2;
//fill array 1
list1.fillArray();
//fill array 2
list2.fillArray();
// print array 1
list1.printForwards();
//print array 2
list2.printForwards();
system("pause");
return 0;
}
Thanks in advance
lists[10]; is not going to create a vector of size 10. It is going to try and access the 11th element of an empty vector. If you wanted to create a vector of size 10 then you can use
Array::Array() : lists(std::vector<int>(10, 0)) {}
I would also suggest you change
Array::Array(vector<int> lists)
{
this->lists = lists;
}
To
Array::Array(vector<int> lists) lists(lists) {}
You should also change your for loops to use the vector size() instead of a hard coded value
void Array::fillArray()
{
for (int i = 0; i < lists.size(); i++) // uses size()
{
cin >> lists[i];
}
}
void Array::printForwards()
{
for (int i = 0; i < lists.size(); i++) // uses size()
{
cout << lists[i];
}
}
Or if you have C++11 or higher you can use a ranged based for loop like
void Array::fillArray()
{
for (auto& e : lists)
{
cin >> e;
}
}
void Array::printForwards()
{
for (const auto& e : lists)
{
cout << e;
}
}