The following code:
#include <cstdio>
#include <iostream>
#include <vector>
template<class type>
struct A {
type i;
A(type j){
i = j;
}
};
template<class type>
std::vector<A<type>*> ve;
int main(int argc, char** args){
ve<int>.push_back(new A<int>(1));
ve<int>.push_back(new A<int>(2));
ve<char>.push_back(new A<char>('a'));
ve<char>.push_back(new A<char>('b'));
for(unsigned int i = 0; i < ve<int>.size(); i++)
std::cout << ve<int>[i]->i << std::endl;
for(unsigned int i = 0; i < ve<char>.size(); i++)
std::cout << ve<char>[i]->i << std::endl;
return 0;
}
outputs:
1
2
a
b
How can I reproduce the same output, but with only one for loop?
Yes I understand the preprocessor made two different vectors here.
Show me how to combine them or show me a generic for loop.
Solution:
#include <cstdio>
#include <iostream>
#include <vector>
struct B {
virtual void memberOut(){}
};
template<class type>
struct A : B{
type i;
A(type j):B(){
i = j;
}
void memberOut(){
std::cout << i << std::endl;
}
};
std::vector<B*> ve;
int main(int argc, char** args){
ve.push_back(new A<int>(1));
ve.push_back(new A<int>(2));
ve.push_back(new A<char>('a'));
ve.push_back(new A<char>('b'));
for(unsigned int i = 0; i < ve.size(); i++)
ve[i]->memberOut();
return 0;
}
Notes:
Either keep it as two containers, or make virtual functions. Both have their uses.
Using a template on a variable just makes two variables.
You can also save another vector of type_index and use typeid to remember what pointer type a void pointer is later on, but that's just a sloppier version of virtual functions. Example:
std::vector<void*> values
std::vector<std::type_index> types
if(types[i]==typeid(A<int>*))
Side Notes:
Try not to get off-base when writing comments.
The objective of comments is to get the question answered, not debate.
Related
I want to store 6 pointers to objects. But the Pointers can be in any order and point to different instances of (12) subclasses of one superclass, so they are possibly all of different types.
Arrays and such don't work, because the superclass is virtual.
Vectors and Tuples don't work, because the datatypes are of no specific order and are not known at compile time.
Im fairly new to C++ and I'm running out of Ideas.
Here some code to elaborate the problem:
baseclass{
getfoobar()=0;
}
subclass1{
getfoobar(){...}
}
subclass2{
getfoobar(){...}
}
---
#include <otherclasses.h>
memoryclass{
baseclass mem[6];
}
is basically what im trying.
You CAN create a vector of superclass pointers. It will achieve what you want, as it will call the overwritten function. This is of course assuming you are talking about inheritance, like:
#include <vector>
using type = ????;
class A {
virtual type foo() = 0;
}
class B : A {
type foo() override { ... }
}
class C : A {
type foo() override { ... }
}
int main(){
std::vector<A*> arr;
arr.push_back(new B);
arr.push_back(new C);
}
Now if I misunderstood and this doesn't work for some reason (i.e. they just share the function and are not actually related classes), you can do something like this, but it is not very nice:
#include <concepts>
#include <vector>
#include <functional>
using type = ?????;
template <class T> requires requires(T t){
{ t.foo() } -> std::same_as<type>;
}
std::function<type()> getFunction(T* t){
return [t](){ return t->foo(); };
}
int main(){
std::vector<std::function<type()>> arr;
arr.push_back(getFunction(new B));
arr.push_back(getFunction(new C));
}
I don't recommend this over the first option unless you have very good reason to do this.
Note: Since you didn't specify return type I winged it with ?????
Also: In the second you can replace template<class T> requires ... std::function<type()>, with just template<class T> std::function<type()>, if the compiler doesn't like #include <concepts>
You can try std::set<Superclass*>. Use pointers to your base superclass instead pointers to particular subclasses.
Actually I used std::shared_ptr<> smart pointer template to avoid raw memory management.
Example code:
#include <cstdlib>
#include <string>
#include <sstream>
#include <set>
#include <memory>
#include <iostream>
class baseclass {
public:
virtual std::string getfoobar() = 0;
};
typedef std::shared_ptr<baseclass> baseclass_ptr;
class subclass1 : public baseclass{
public:
std::string getfoobar() override {
return "from subclass1";
}
};
class subclass2 : public baseclass{
public:
std::string getfoobar() override {
return "from subclass2";
}
};
int main(int argc, char** argv) {
// Use current time as seed for random generator
std::srand(static_cast<unsigned>(std::time(nullptr)));
std::set<baseclass_ptr> container;
// Randomly generate number of elements
const int random_count = std::rand() % 10 + 1;
for (int i = 0; i < random_count; ++i) {
// Randomly create subclass1 or subclass2
if (std::rand() % 2) {
container.insert(std::make_shared<subclass1>());
}
else {
container.insert(std::make_shared<subclass2>());
}
}
// Iterate resulting container
std::cout << "size = " << container.size() << std::endl;
for (auto iterator : container) {
std::cout << "getfoobar(): " << iterator->getfoobar() << std::endl;
}
return 0;
}
I have to use a struct array called Robot_parts[] for each part_rect struct (part_num, part_name, part_quantity, part_cost)
And through the void display function, I have to display Robot_parts[] array entirely through pointer but I don't know how, and I don't know where to declare Robot_parts[] and whether i have to put any number value inside the brackets.
So far I have:
#include <iostream>
#include <string>
using namespace std;
void display();
struct part_rec
{
int part_num;
string part_name;
int part_quantity;
double part_cost;
};
int main()
{
part_rec Robot_parts[ ] = {
{7789, "QTI", 4, 12.95},
{1654, "bolt", 4, 0.34},
{6931, "nut", 4, 0.25}
};
return 0;
}
void display()
{
cout<<Robot_parts[]<<endl<<endl;
}
If I also made a few other errors, please let me know. Thanks!
As stated in a comment it would be much better to use a c++ container like a std::vector or std::array.
But since your professor requires an old-style array, you could try like the code below - see the comments for explanation:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
struct part_rec
{
int part_num;
string part_name;
int part_quantity;
double part_cost;
};
// You have to pass a pointer (to the array) and the size of the array
// to the display function
void display(part_rec* Robot_parts, int n);
// Make a function so that you can "cout" your class directly using <<
// Note: Thanks to #BaumMitAugen who provided this comment and link:
// It makes use of the so called Operator Overloading - see:
// https://stackoverflow.com/questions/4421706/operator-overloading
// The link is also below the code section
std::ostream &operator<<(std::ostream &os, part_rec const &m)
{
// Note - Only two members printed here - just add the rest your self
return os << m.part_num << " " << m.part_name;
}
int main()
{
part_rec Robot_parts[] {
{7789, "QTI", 4, 12.95},
{1654, "bolt", 4, 0.34},
{6931, "nut", 4, 0.25}
};
display(Robot_parts, 3);
return 0;
}
void display(part_rec* Robot_parts, int n)
{
// Loop over all instances of your class in the array
for (int i = 0; i < n; ++i)
{
// Print your class
cout << Robot_parts[i] << endl;
}
}
The link recommended by #BaumMitAugen:
Operator overloading
The code should explain my difficulty. Though the code itself is quite meaningless, I'm planning to add containers in MyClass, and use algorithms with member functions.
#include <cstdlib>
#include <algorithm>
#include <functional>
using namespace std;
class MyClass
{
public:
MyClass() { a = 0; }
~MyClass() {}
private:
int a;
bool tiny_test (int);
int Func();
};
bool MyClass::tiny_test (int b)
{
return a == b;
}
int MyClass::Func()
{
// does not compile
(mem_fun(&MyClass::tiny_test))(this);
// commented below is another attempt, also no success
//mem_fun1_t<bool, MyClass, int> tmp_functor = mem_fun(&MyClass::tiny_test);
//tmp_functor(this);
return 0;
}
int main(int argc, char** argv)
{
return 0;
}
Thanks a lot! Btw, I'm not using a static member function, simply because I believe it must work for non-static member functions.
P.S. Eric, Jarod42, thanks for prompt replies!
bool MyClass::tiny_test (int b)
{ // ^^^^^ You missed this argument
return a == b;
}
Try this:
// Supply one more argument. E.g., 3
(mem_fun(&MyClass::tiny_test))(this, 3);
How could I keep an object valid in a different class? Here is an example below.
This code would give as a result on the screen:
2
2
What I want is to give me this:
2
3
In other words, I desire object Bita (or even the whole class two) to acknowledge object Alpha and not create a new object.
Is there a way to include the object Alpha to object Bita ? Please be simple because I am a beginner.
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <stdlib.h>
#include <stdio.h>
using namespace std;
class one
{
int a, b;
public:
one() { a = 2; }
int func()
{
return a;
}
void func2()
{
a = 3;
}
};
class two
{
int z, b;
public:
void test();
};
void two::test()
{
one Alpha;
cout << Alpha.func() << '\n';
}
int main()
{
one Alpha;
cout << Alpha.func() << '\n';
Alpha.func2();
two Bita;
Bita.test();
return 0;
}
Each instance of an object has its own values for its member variables. So when you declare two Bita, and call Bita.test(), test() creates its own object of class Alpha inside of it, with its own value, which is still at 2, prints that, and then that Alpha object goes out of scope and is removed from the stack as test() completes.
What you say you have in mind to do here is to have class one have what is called a static member variable. Add the keyword static:
static int a;
And then a will behave as you intend.
One explanation of this is here: http://www.learncpp.com/cpp-tutorial/811-static-member-variables/
One solution would be to pass the object by reference you method two::test like this
class two
{
int z, b;
public:
void test(one& a);
};
void two::test(one& a)
{
cout << a.func() << '\n';
}
And then call it in main
Bita.test(Alpha);
So the full code will be
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <stdlib.h>
#include <stdio.h>
using namespace std;
class one {
int a, b;
public:
one() { a = 2; }
int func() { return a; }
void func2() { a = 3; }
};
class two {
int z, b;
public:
void test(one&);
};
void two::test(one& a) {
cout << a.func() << '\n';
}
int main() {
one Alpha;
cout << Alpha.func() << '\n';
Alpha.func2();
two Bita;
Bita.test(Alpha);
return 0;
}
I want to send my Array class using boost Mpi
template<class T>
class Array
{
private:
int size;
T* data;
public:
// constructors + other stuff
};
Here T can be any built in type or user defined type. Suppose I have a class complex
struct complex
{
std::vector<double> real_imag; // contain two elements
};
So the question is how can I send Array<complex> using Boost::Mpi + serialization.
Thanks in anticipation
Regards
Noman
Why don't you use STL vector instead of your own Array class. The serialization of STL-vectors is already build in in boost/serialization/vector.hpp. If you want to send an array of complex numbers you could you something like this:
#include <vector>
#include <boost/mpi/environment.hpp>
#include <boost/mpi/communicator.hpp>
#include <boost/serialization/complex.hpp>
#include <boost/serialization/vector.hpp>
using namespace std;
namespace mpi=boost::mpi;
int main (int argc, char *argv[])
{
mpi::environment env(argc, argv);
mpi::communicator world;
int myid=world.rank();
int NN=world.size();
int N=10;
vector< complex<double> >A(N);
if (myid==0)
{
for (int i=0; i!=N; i++)
{
A[i]=complex<double>(i, i);
}
world.send(1, 0, A);
}
if (myid==1)
{
world.recv(0, 0, A);
cout << "###" << endl;
for (int i=0; i!=N; i++)
{
cout << A[i] << "\t" ;
}
cout << endl;
cout << "###" << endl;
}
}
If not, you have to make the datatype which is content of your vector is serializable. If the serialization of that datatype is not part of the boost serialization library you have to write your own serialization. For example for your complex struct from above somethink like this should do the trick (not tested):
namespace boost
{
namespace serialization
{
template<class Archive>
void serialize(Archive & ar, complex & c, const unsigned int version)
{
ar & c.real_imag;
}
}
}
But as I said, the STL complex type is already build in in boost serialization.