#include<iostream>
using namespace std;
class Alpha
{
int a;
public:
void get_a(int x)
{
a = x;
}
int hello()
{
return a;
}
};
class Beta : public Alpha
{
int b, c;
public:
void get_b(int y)
{
b = y;
}
void add()
{
c = hello() + b;
cout << c << endl; // displays garbage value
}
};
int main()
{
Alpha v1;
Beta v2;
v1.get_a(4);
v2.get_b(3);
v2.add();
v2.disp();
return 0;
}
The output of v2.disp() shows garbage value but when I initalise "a" as v2.get_a instead of v1.get_a , it shows the correct answer. New to C++ btw. Please help. Thanks.
The problem is that you have two different objects that are unrelated to each other. The object v1 is unrelated to the object v2, they are separate and distinct objects. You initialize Alpha::a with v1.get_a(4), that doesn't initialize Beta::a.
A solution to your problem is to use one object:
Beta v;
v.get_a(4);
v.get_b(3);
v.add();
v.disp();
Related
#include <iostream>
using namespace std;
class Complex{
private:
int a,b;
public:
void set_data(int x,int y){
a=x,b=y;
}
void show_data(){
cout<<a<<" "<<b<<endl;
}
};
Complex add(Complex c, Complex d){
Complex temp;
int a = c.a+c.b;
int b = d.a+d.b;
temp.set_data(a,b);
return temp;
};
int main()
{
Complex c1,c2,c3;
c1.set_data(2,3);
c2.set_data(4,5);
c3 = add(c1,c2);
c3.show_data();
return 0;
}
want to know why add function is not wrking where as if i write c1.add(c2) and define function inside class then it works completely fine
"a" and "b" are declared as private. You cannot access it from outside the class. You need to make it public or provide getters or move it to inside the class.
As others pointed out, the member variables "a" and "b" are private and therefore can't be accessed from outside the class. Also, mind that your "add" function may not be mathematically correct. If you mean to add two complex numbers you probably want to write:
int a = c.a + d.a;
int b = c.b + d.b;
where I assume "a" is the real part and "b" the imaginary part
As the class variables "a" and "b" are private, you need to write getter functions for them. Sample code as follows:
#include <iostream>
using namespace std;
class Complex{
private:
int a,b;
public:
void set_data(int x,int y){
a=x,b=y;
}
void show_data(){
cout<<a<<" "<<b<<endl;
}
int getA(){
return a;
}
int getB(){
return b;
}
};
Complex add(Complex c, Complex d){
Complex temp;
int a = c.getA()+c.getB();
int b = d.getA()+d.getB();
temp.set_data(a,b);
return temp;
}
int main()
{
Complex c1,c2,c3;
c1.set_data(2,3);
c2.set_data(4,5);
c3 = add(c1,c2);
c3.show_data();
return 0;
}
Or make the variables public to directly access from anywhere. Sample as follows:
#include <iostream>
using namespace std;
class Complex{
public:
int a,b;
public:
void set_data(int x,int y){
a=x,b=y;
}
void show_data(){
cout<<a<<" "<<b<<endl;
}
};
Complex add(Complex c, Complex d){
Complex temp;
int a = c.a+c.b;
int b = d.a+d.b;
temp.set_data(a,b);
return temp;
};
int main()
{
Complex c1,c2,c3;
c1.set_data(2,3);
c2.set_data(4,5);
c3 = add(c1,c2);
c3.show_data();
return 0;
}
So, there's a lot to discuss here and it's a bit tough because it's hard to know what you're allowed to use. I've tried to remove that notion from my courses, at least.
Your class lacks any constructors. Relying solely on a setter is poor practice. Constructors are the correct way to initialize an object, and they are more efficient than a default initialization + setter.
You overuse the comma operator for no real gains. It just muddies readability.
Your add() function attempted to access private data, that's a big no-no. It would defeat the purpose if any free function could access private data as it pleased. The reason implementing the function inside the class worked fine is because as a class member function, it has access to the private section. Either make it a class member funtion OR add getters for your data.
The following sample adds constructors, replaces functions with operator overloads where they fit, and made a few other "better" practice changes. It also includes functionality that is available in C++17.
When I help with homework questions like this, my preference is to use a couple things that are likely to have not been discussed yet; it helps prevent copy/paste dishonesty. But I believe it still helps in seeing the logic play out.
#include <iostream>
#include <string>
#include <tuple>
class Complex {
public:
Complex() = default;
Complex(int r, int i) : m_real(r), m_imaginary(i) {}
auto get_data() const { return std::make_tuple(m_real, m_imaginary); }
void set_data(int x, int y) {
m_real = x;
m_imaginary = y;
}
private:
int m_real = 0;
int m_imaginary = 0;
};
Complex operator+(const Complex& lhs, const Complex& rhs) {
auto [leftReal, leftImaginary] = lhs.get_data(); // C++17 feature
auto [rightReal, rightImaginary] = rhs.get_data();
return Complex(leftReal + rightReal, leftImaginary + rightImaginary);
}
// No newline printed here because no other Standard type does that
std::ostream& operator<<(std::ostream& sout, const Complex& obj) {
auto [real, imaginary] = obj.get_data();
// If you care about setw() interacting with your output, this intermediate
// step matters
std::string val =
std::to_string(real) + " + " + std::to_string(imaginary) + "i";
return sout << val;
}
int main() {
Complex c1(2, 3);
Complex c2(4, 5);
Complex c3 = c1 + c2;
std::cout << c3 << '\n';
return 0;
}
I'm having a problem of storing data into the private array in a class.
I tried to Google and didn't find any solution.
Here's my code:
Foo.h
class Foo {
private:
int arr[10];
double d;
public:
Foo::Foo(double d) {
this->d = d;
}
// ...
};
Foo.cpp
int main() {
double d = 123.456;
int array[10];
// Getting data from user input by for-loop 10 times.
Foo f = Foo(d);
And here's my problem -- how to save the array into the f?
Seems like using pointer (*f.arr = array;) doesn't acturally change the arr.
I tried this solution by adding
class Foo {
// ...
Public:
Foo::Foo(int arr_, double d_) : arr_(new int[10]), d_(d) { };
But the Visual Studio 2017 says the array is not initialized.
I also tried this solution, but VS says cannot modify the array in this scope.
Please help. Thank you in advance.
#include <algorithm> // std::copy()
#include <iterator> // std::size()
class Foo {
private:
int arr[10];
double d;
public:
Foo(double d, int *data)
: d{ d }
{
std::copy(data, data + std::size(arr), arr);
}
// ...
};
class book{
private:
int numOfPages;
public:
book(int i){
numOfPages = i;
};
};
class library{
private:
book * arrOfBooks;
public:
library(int x, int y){
arrOfBooks = new book[x](y);
};
};
int main()
{
library(2, 4);
};
With the example code above I would like to create a library of books that all have the same number of pages. So in the constructor of the library object, whenever a new book is created to be placed in the array I pass the argument in the parenthesis.
The above code when tested in C++ shell shows error: "parenthesized initializer in array new".
This is for the completion of a school project and no vectors are allowed (as it would be wise to do as I found doing my research) though I cannot think of any other ways to do it than the one shown above...
There is no syntax for initializing elements of a dynamic array using a non-default constructor.
You have to create the array first, then loop over the elements and assign each individually. Possibly the simplest way to do that is to use std::fill.
Array of books is a one dimensional array and it should be defined as follows:
library(int x)
{
arrOfBooks = new book[x];
};
If you have an assumption all books have same page you have pass it as a default parameter to your book class constructor:
book(int i=200)//set the defautlt value here
{
numOfPages = i;
};
Using templates:
#include <iostream>
template <int book_capacity> class book
{
private:
int numOfPages;
public:
book(): numOfPages(book_capacity){}
};
template <int lib_capacity, int book_capacity> class library
{
private:
book<book_capacity> arrOfBooks[lib_capacity];
int cnt;
public:
library(): cnt(0) {}
void addBook(book<book_capacity> b)
{
if (cnt < lib_capacity)
{
arrOfBooks[cnt] = b;
cnt++;
std::cout << "book is added" << std::endl;
return;
}
std::cout << "library is full" << std::endl;
}
};
int main()
{
library<2, 4> lib;
book<4> b;
lib.addBook(b);
lib.addBook(b);
lib.addBook(b);
lib.addBook(b);
system("pause");
return 0;
}
i want to write a function which takes in a vector of objects and name of one of their property. then it will do some manipulation based on the values of that property of the objects.finally will return an object.
eg.
class A{
Point center;
int length;
...
...
};
class B{
Point position;
bool value;
...
...
};
now if we pass the function a vector of type A, it should manipulate the objects based on the value of center; if we pass the function a vector of type B, it should manipulate the objects based on values of position.
functiona(vector<T>,string property)
inside the function how can i access a property based in the passed string property??
EDIT: the 2nd property being string is just for illustration; i don't care what type it is
Yes, it can be done using pointers-to-members. Example use:
#include <iostream>
#include <vector>
using namespace std;
class A {
public:
int a;
A(int x):a(x){}
};
class B {
public:
int b;
B(int x):b(x){}
};
template <typename T> int func(vector<T> data, int T::*pointer) {
int total = 0;
for (unsigned i = 0; i < data.size(); ++i) {
total += data[i].*pointer;
}
return total;
}
int main() {
vector<A> vec1;
vec1.push_back(A(123));
vec1.push_back(A(456));
vec1.push_back(A(789));
vector<B> vec2;
vec2.push_back(B(666));
vec2.push_back(B(666));
vec2.push_back(B(666));
cout << func(vec1, &A::a) << endl;
cout << func(vec2, &B::b) << endl;
return 0;
}
You declare a pointer-to-member as such: valueType class::*pointerName, read adresses as such: &class::field and use them like that: object.*pointerToMember or pointerToObject->*pointerToMember.
how to customise a c++ list container such that it can holds different type of struct ?
for example
struct A
{
int a;
int b;
}
struct B
{
float a;
float b;
}
#include <list>
using namespace std;
int main()
{
...
...
A a;
a.a = 1;
a.b = 2;
B b;
b.a = 123.444;
b.b = 11.222;
List.push_back(a);
List.push_back(b);
return 0;
}
Why not polymorphism and a list of pointers to the objects?
Be careful about object lifetime. The pointers in the list will become invalid once the two objects go out of scope. You can alternatively dynamically allocate (new) the two elements and delete them when you're done, then remove them from the list.
Later edit: I get the feeling you are new to C++. After studying dynamic allocation, I recommend you look up smart pointers. They lift the burden of manually managing memory by doing it themselves:
unique_ptr and
shared_ptr
You can use them inside the list instead of naked pointers.
struct Base
{
virtual ~Base(){}
};
struct A : public Base
{
int a;
int b;
};
struct B : public Base
{
float a;
float b;
};
#include <list>
using namespace std;
int main()
{
...
...
A a;
a.a = 1;
a.b = 2;
B b;
b.a = 123.444;
b.b = 11.222;
std::list<Base*> l;
l.push_back(&a);
l.push_back(&b);
return 0;
}
In some cases it makes sense to store different types in a container. C++ supports these use cases with unions, but this feature is very basic. I recommend using boost::variant instead of unions if you really need to store different types in a container. I also recommend using std::vector instead of std::list, because otherwise it doesn't make much sense to use this optimization.
Here is an example with boost::variant:
std::vector<boost::variant<A, B>> items;
A a = ...;
B b = ...;
items.push_back(a);
items.push_back(b);
struct get_length : boost::static_visitor<double>
{
double operator()(const A& f) const { return calc(f.a, f.b); }
double operator()(const B& b) const { return calc(b.a, b.b); }
double calc(double a, double b) const { return std::sqrt(a * a + b * b); }
};
for (auto&& item : items) {
double d = boost::apply_visitor(get_length(), item);
std::cout << d << '\n';
}
I suggest boost:: any. But really, does polymorphism not solve your problem?