I am confused on how to fill a vector with values from a different class.
Can anyone give me a coded example how this is done. :)
Class A
{
//vector is here
}
Class B
{
//add values to the vector here
}
main()
{
//access the vector here, and print out the values
}
I appreciate the help <3
It seems like a quick lesson in access levels and encapsulation is in order.
My guess, based on the questions touch is that you're looking for the following code.
int main()
{
ClassA[] as = {new ClassA(), new ClassA(), ... }
ClassB[] bs = {new ClassB(), new ClassB(), ... }
}
But I'm shooting in the dark, a bit. :)
You should make your question more specific, edit it and post what you've tried to do. If you mean to do something respecting oop-rules, the play looks like this:
#include<iostream>
#include<vector>
class A{
public:
void fill_up_the_vector() { v=std::vector<int>(3); v[0]=0; v[1]=1; v[2]=4; }
void add( a.add(i); ) { v.push_back(i); }
void display_last() const { std::cout<<v[v.size()-1]; }
private:
std::vector<int> v;
};
class B{
public:
B(){ a.fill_up_the_vector(); } // B just *instructs* A to fill up its vector.
void add_value(int i) { a.add(i); }
void display() const { a.display_last(); }
private:
A a;
};
int main()
{
B b;
b.add_value(9);
b.display(); // reads v through A.
}
Note that this example above is a bit different from what you've asked. I posted it since I think you sould keep in mind that according to OOP rules
you don't want to access values in A directly,
B should have a member with type A if you plan to access a value in A,
you're supposed to access a value in A through B if you have filled it up from B.
The other way to go is not OOP:
struct A{
std::vector<int> v;
};
struct B{
static void fill_A(A& a) const { a.v = std::vector<int>(3); a.v[0]=0; a.v[1]=1; a.v[2]=4; }
};
int main()
{
A a;
B::fill_A(a);
a.v.push_back(9);
std::cout << a.v[a.v.size()-1];
}
but this code is as horrible as it gets.
Related
class C {
public: void c_set(int x){ a = x; }
private: int a;
}
;
class U {
public: void load();
c_loader(int i, int x){ c[i].c_set(x); };
private: vector<C> c(20);
}
;
void U::load() {
int x;
cin >> x >> i;
c_loader(i, x)
}
I'm really confused with this one. I need to call a member function in another one but my problem is that the inside class is a vector of that classes. My code is supposed to work but the result is segfault. Presume that the function cget has definition.
The question is a bit unclear but try this to prevent segfault.
class C {
public: void cget(int a);
private: int a;
};
class U {
public: void load();
vector<C> c; // Note: c is made public in order to add elements from main
};
void U::load(unsigned x, int a) {
if (x < c.size()) // Check the size of c _before_ access
{
c[x].cget(a);
}
}
void main()
{
U u;
C c;
u.c.push_back(c);
u.load(0, 3); // Will end up calling cget
u.load(1, 3); // Will just return without calling cget
}
EDIT:
Just want to mention that the code in the question has changed a lot sinse my answer. That explains why my code looks quite different ;-)
In any case, the answer is still: Check the size of c before accessing it.
As an example, I have this case, in which the classes A and B perform the same expensive calculation, the function expensiveFunction. This function is "pure", in that I can guarantee that it will give the same result given the same input. The client may use both classes (or more similar classes) with the same input, and I would wish that the expensensive function is only calculated once. However, the client may also only use one class for a given input.
Code example:
class A {
public:
A(const InputData& input) {
res = expensiveFunction(input);
}
void foo(); //Use the expensive result
private:
ExpensiveResult res;
};
class B {
public:
B(const InputData& input) {
res = expensiveFunction(input); //Same function as in A
}
double bar(); //Use the expensive result
private:
ExpensiveResult res;
};
int main() {
//Get some input
//...
A a(input);
B b(input);
//Do stuff with a and b
//More input
A a2(otherInput);
//...
}
In some languages, due to referential transparency and memoization, it can safely compute it only once for a given input.
What I have thought of is using some sort factory method/class, or give a function object/functor/supension to the A and B classes that stores the result.
What are some good design ideas to solve this problem?
I own all of the code, so I can change the client or the service classes if necessary.
You can memoize just inside of your function
COutput expensive(CInput input) {
static std::map<CInput, COutput> memoized_result;
auto resit = memoized_result.find(input);
if (resit == memoized_result.end()) {
// ... do calculations
output = expensiveCalculation(input);
resit = memoized_result.insert(std::make_pair(input, output));
}
return resit->second;
}
The result of your computation is stored in the static map (memoized_result), and persisted between function calls.
If input is too expensive to use as a key in the map, you can create a separate class for handling computation result, and share it between all clients:
#include <memory>
using namespace std;
class ExpensiveResult {
public:
ExpensiveResult(int input) {
out_ = input+1;
}
int out_;
};
class BaseCompResultUser {
public:
BaseCompResultUser(const std::shared_ptr<ExpensiveResult>& res) {
res_ = res;
}
private:
std::shared_ptr<ExpensiveResult> res_;
};
class A : public BaseCompResultUser {
public:
A(const std::shared_ptr<ExpensiveResult>& r) : BaseCompResultUser(r) { }
};
class B : public BaseCompResultUser {
public:
B(const std::shared_ptr<ExpensiveResult>& r) : BaseCompResultUser(r) { }
};
int main() {
std::shared_ptr<ExpensiveResult> res(new ExpensiveResult(1));
A a(res);
B b(res);
return 0;
}
This will force sharing computation result between objects.
I think that the object-oriented way of solving it is for the expensiveFunction to be a member function of InputData (or some wrapper of InputData) and then your problem pretty much goes away. You just make ExpensiveResult a mutable cache in InputData:
class InputData {
private:
mutable std::shared_ptr<ExpensiveResult> result_;
public:
InputData() : result_(nullptr) {}
std::shared_ptr<ExpensiveResult> expensiveFunction() const {
if (!result_) {
// calculate expensive result...
result_ = std::make_shared<ExpensiveResult>();
}
return result_;
}
};
The expensive calculation is only done the first time expensiveFunction is called. You might have to add some locking if this is being called in a multi-threaded way.
If ExpensiveFunction does the same thing in A and B, it hardly seems like a true member of either. Why not a function?
int main() {
//Get some input
//...
res = expensiveFunction (input) ;
A a(res);
B b(res);
//Do stuff with a and b
//...
}
First of all sorry if i've chosen wrong title, but wasn't sure how to name it.
Code structure first:
//== 1st file ==
class A {
private:
int x;
public:
int GetX() { return x; }
};
//== 2nd file ==
class B {
private:
A ob1;
public:
virtual A & GetARef() { return ob1; }
};
class C : public B {
private:
A ob2;
public:
A & GetARef() { return ob2; }
};
class D : public B {
public:
// something else w/e
};
//== 3rd file ==
class E {
private:
std::map <int,C> m;
public:
C* GetCPtr(int idx) { return &m[idx]; }
};
//== 4th file ==
void foo(E & E_Obj) {
std::vector <B*> v;
v.push_back(E_Obj.GetCPtr(0));
v.push_back(/*some pointer to D class*/);
Boo(v); // FORGOT TO ADD IT ! Sorry
};
//== 5th file ==
void Boo(std::vector <B*> & v) {
std::cout << v[0]->GetARef().GetX(); // returns B::ob1 's x instead of C::ob2 's x.
};
As wrote in comments, Boo gets wrong 'x'. I just wonder if it's because that pointers go 'out of scope' or I misdesigned something wrong. How to fix that, so I can get proper x (C::ob2 's one).
Sorry for kinda strange class names etc., but orginal code is much longer, so I tried to show the situation only.
#edit
Forgot to add that in Foo() it returns what i expect - C::ob2 's x.
This is the essence of what you are doing
#include <iostream>
using namespace std;
class Base{
const int b = 0;
public:
virtual const int& getInt(){
return b;
}
};
class LeafOverriding : public Base{
const int l = 1;
public:
virtual const int& getInt(){
return l;
}
};
class Leaf : public Base{
};
int main(){
cout << Leaf().getInt() << '\t' << LeafOverriding().getInt() << endl;
}
and it has no problems (i.e. it does indeed output 0 1). I would say that your snippet -- which does not compile, btw -- does not represent the real code.
I'm so lazy I forced you to compile it with C++11 support, because of const int b = 0 and const int l = 1 :)
Sorry for not leaving reply in comments, but I decided it's worth whole post. Also sorry for such late reply. I've spent whole day and night digging slowly through code, since you've proved that my coding was fine (except few typos in example code, sorry for that). Practically after rewriting code letter after letter I finally found the troublemaker somewhere I would normally never look for. My co-worker while sorting some things was switching not the pointers in related vector but their content.
Something like that
vector <E*> v;
// ...
*v[i] = ...
instead of
v[i] = ...
After fixing that, it indeed works as intented. Thanks for your help and clearing things out. Also sorry for wasting your time.
I have a function which has two parameters, both objects. I change these objects inside the function and I need to see the changes afterwards. But pointers does not work. Any idea?
void foo(apple &a,apple &b)
{
//change a and b
}
main()
{
apple a,b;
foo(a,b);
//a and b are the same as befor calling foo `
}
thanks.
Do you mean changing the methods of the classes you're passing? You'll need to use '->' if that's what you mean.
class apple {
public:
int weight;
}
void foo(apple *a,apple *b) {
a->weight = b->weight;
}
main() {
apple a,b;
foo(&a,&b);
}
For a constructor with multiple arguments...
For example:
class C {
public:
C(int a=1, int b=2){ cout << a << ", " << b << "\n"; }
}
int main(){
C a(10), b = 20;
}
output:
10, 2
20, 2
How do I just assign value to the 2nd parameter? So that I can get "1, 20" without knowing the default values? Or is that that I must always assign value to the argument that precedes before I can use the arguments behind?
And how do I implicitly assign all the parameters? If I can't do that, why? For the above example (as I am new to C++), I once thought I would get "10, 20" as output instead.
Or is that that I must always assign value to the argument that precedes before I can use the arguments behind?
Yes. Otherwise, how is the compiler supposed to know which argument should be used for which parameter?
However, there are ways to accomplish this. For example,
struct C {
enum { DefaultA = 1, DefaultB = 2 };
C(int a = DefaultA, int b = DefaultB) { /* ... */ }
};
C object(C::DefaultA, 20);
Or, if you have a lot of parameters with different "defaults:"
struct CParams {
int a, b;
CParams() : a(1), b(2) { }
};
struct C {
C(CParams x) { /* ... */ }
};
CParams params;
params.b = 20;
C object(params);
C++ doesn't support named arguments. You have to specify the first one.
Also, the variable name b from the main function is completely separate from the b in the constructor definition. There's no relationship whatsoever implied by the naming.
I had the same thought (Convienient C++ struct initialisation -- perhaps you find something you like better there) some time ago, but just now, reading your question, I thought of a way to actually accomplish this. But it is quite some extra code, so the question remains if it is actually worth it. I just implemented it very sketchy and I am not proud of my choice of names (I usually don't use _ but it's late). Anyway, this is how you can do it:
#include <iostream>
struct C_members {
int a;
int b;
C_members(int _a, int _b) : a(_a), b(_b) {}
};
class C_init {
public:
virtual C_members get(C_members init) const {
return init;
}
};
class C_a : public C_init {
private:
int a;
public:
C_a(int _a) : a(_a) {}
C_members get(C_members init) const {
init.a = a;
return init;
}
};
class C_b : public C_init {
private:
int b;
public:
C_b(int _b) : b(_b) {}
C_members get(C_members init) const {
init.b = b;
return init;
}
};
class C : private C_members {
private:
static const C_members def;
public:
C(C_init const& ai = C_init(), C_init const& bi = C_init()) : C_members(ai.get(bi.get(def)).a, bi.get(ai.get(def)).b) {
std::cout << a << "," << b << std::endl;
}
};
const C_members C::def(1,2); // default values
// usage:
int main() {
C c1(C_b(77)); // 1,77
C c2(C_a(12)); // 12,2
C c3(C_b(5),C_a(6)); // 6,5
return 0;
}
There is a lot of stuff that can be improved (with templates (for code reduction) and with const refs in the get method), but you get the idea.
As a bonus feature, you almost have the pimpl idiom implemented (very little effort is necessary to extend this to an actual pimpl design).
Usually in OOP, every object instance holds (and represents) a state.
So the best way is to define an accessor functions such as
void setB(int newBvalue);
and also to hold b as a private member.
if "b" is shared among all the instances of the same object, consider to save a static variable.