why i can't use array of references
Jan 28, 2010 at 10:49am UTC
hi, yesterday i read about arrays, and surprised when i read that C++ doesn't support array of references. my main question is why, is there any reasons?
Jan 28, 2010 at 12:28pm UTC
Because references aren't considered objects by the language, unlike integers, pointers, etc. You also can't have pointers to references and you can't dynamically allocate references. There are only two valid uses of references:
1 2 3
T &r=/*...*/ ;
T f(/*...*/ T2 &p/*...*/ ){/*...*/ }
All these restrictions come from the fact that the language doesn't allow uninitialized references.
EDIT: Oh, they can also be class members, but they have to be initialized in an initialization list in the constructor, and having at least one reference as a class member makes the class uncopyable.
Last edited on Jan 28, 2010 at 12:55pm UTC
Jan 29, 2010 at 9:42am UTC
...and having at least one reference as a class member makes the class uncopyable
That almost sounds like a challenge.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
#include <iostream>
template <typename T>
class Ref
{
public :
Ref(T &val) : ref(val) { }
Ref(const Ref &other) : ref(other.ref) { }
Ref & operator =(const Ref &other)
{
if (&other != this )
{
this ->Ref::~Ref(); // Evil
new (this ) Ref(other); // Evil
}
return *this ;
}
Ref & operator =(const T &val)
{
ref = val;
return *this ;
}
operator T() const
{
return ref;
}
private :
T &ref;
};
int main(int argc, char *argv[])
{
// Initialise a reference
int i(10);
Ref<int > ref1(i);
std::cout << ref1 << std::endl;
// Change i by reference
ref1 = 13;
std::cout << i << std::endl;
// Copy to int by value
int k(ref1);
std::cout << k << std::endl;
// "Copy" a reference :P
Ref<int > ref2(ref1);
std::cout << ref2 << std::endl;
i = 12;
std::cout << ref1 << std::endl;
std::cout << ref2 << std::endl;
// "Reassign" a reference :P
int j(5);
Ref<int > ref3(j);
std::cout << ref3 << std::endl;
ref3 = ref1;
std::cout << ref3 << std::endl;
return 0;
}
which produces
Edit: Added conversion operator.
Last edited on Jan 29, 2010 at 10:21am UTC
Jan 29, 2010 at 10:44am UTC
@SCSI 73rm1n8r
wow, that is indeed evil !!!
Jan 29, 2010 at 12:43pm UTC
Not as evil as this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
int a1(0), a2(1), a3(2), a4(3);
// Not too evil
Ref<int > staticRefArray[] = {a1, a2, a3, a4};
std::cout << staticRefArray[0] << " "
<< staticRefArray[1] << " "
<< staticRefArray[2] << " "
<< staticRefArray[3] << std::endl;
// Now with an STL container
std::vector<Ref<int > > vectorRef;
vectorRef.push_back(a1);
vectorRef.push_back(a2);
vectorRef.push_back(a3);
vectorRef.push_back(a4);
std::cout << vectorRef[0] << " "
<< vectorRef[1] << " "
<< vectorRef[2] << " "
<< vectorRef[3] << std::endl;
// Now the hard way (circumventing the default constructor requirement for dynamic arrays)
Ref<int > *dynamicRefArray = static_cast <Ref<int >*>(::operator new (sizeof (Ref<int >)*4));
new (&dynamicRefArray[0]) Ref<int >(a1);
new (&dynamicRefArray[1]) Ref<int >(a2);
new (&dynamicRefArray[2]) Ref<int >(a3);
new (&dynamicRefArray[3]) Ref<int >(a4);
std::cout << dynamicRefArray[0] << " "
<< dynamicRefArray[1] << " "
<< dynamicRefArray[2] << " "
<< dynamicRefArray[3] << std::endl;
dynamicRefArray[0].~Ref();
dynamicRefArray[1].~Ref();
dynamicRefArray[2].~Ref();
dynamicRefArray[3].~Ref();
::operator delete (dynamicRefArray);
Jan 29, 2010 at 12:59pm UTC
It all screams "abuse" to me, anyway.
Topic archived. No new replies allowed.