Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » template parameter automatisch

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
03.02.2009, 08:57 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


Hallo,

ich hab im moment folgendes Template:


C++:
template <class Type, class Allocator>
class SerializableArray
{
// ...

Type *values = new Allocator[anzahl];

// ...
};



Nun muss ich aber z.b


C++:
class MyObjectArray: public SerializableArray<MyObject, MyObject>
{
};



schreiben, bei map, vector usw muss man den allokator ja nicht zwingend angeben - wie machen die das?
--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
03.02.2009, 09:42 Uhr
0xdeadbeef
Gott
(Operator)



C++:
template<typename Type, typename Allocator = Type>
class SerializableArray {
  // ...
};


...allerdings ist die Nomenklatur hier etwas irreführend, dein "Allocator" ist ja nicht wirklich ein Allokator. Vielleicht sinnvoller wäre etwas wie

C++:
template<typename T> struct array_allocator {
  T *operator()(std::size_t n) { return new T[n]; }
};

template<typename Type, typename Allocator = array_allocator<Type> >
class SerializableArray {
public:
  SerializableArray(std::size_t n);
  // ...

private:
  Type *data_;
};

SerializableArray::SerializableArray(std::size_t n) {
  Allocator alloc;
  data_ = alloc(n);
}


--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
03.02.2009, 10:16 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


Hmm okay, auf das einfachste kommt man natürlich wieder net

Und hast recht "Allocator" ist evtl irreführend evtl nenn ichs einfach TypeUsedByAllocationWhichShouldBeSubClassOfType
--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
03.02.2009, 10:24 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


okay noch was anderes:


C++:
template<typename Type, typename Allocator = Type>
    SerializableArray& operator= (const SerializableArray &other)
    {
        alloc(other.getCount());

        for(unsigned int i = 0; i < other.getCount(); ++i)
            elements[i] = other.elements[i];

        return *this;
    }



Problem nun:


C++:
class A {};
class B : public A {};

class AArray : public SerializableArray<A> { };
class BArray : public SerializableArray<A, B> { };

BArrayInstance = AArrayInstance; // Kann nicht zugewiesen werden



Wie muss ich den oberen operator ändern, damit er so etwas akzeptiert? Die klasse (A) selbst hat einen zuweisungsoperator, das elements[i] = other.elements[i] sollte allso nicht das problem darstellen, sondern eher das der nur einen operator= für <A,A> und nicht für <A, B> hat?
--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
03.02.2009, 15:21 Uhr
0xdeadbeef
Gott
(Operator)


Etwa so:

C++:
#include <cstddef>
#include <iostream>

template<typename Type, typename Allocated = Type>
class SerializableArray {
public:
  SerializableArray()              : data_(NULL), size_(0) { }
  SerializableArray(std::size_t n) : data_(NULL), size_(0) { alloc(n); }

  ~SerializableArray() { delete[] data_; }

  std::size_t size() const { return size_; }

  Type       &operator[](std::size_t index)       { return data_[index]; }
  Type const &operator[](std::size_t index) const { return data_[index]; }

  template<typename T, typename A>
  SerializableArray &operator=(SerializableArray<T, A> const &other) {
    alloc(other.size());

    for(std::size_t i = 0; i < size(); ++i) {
      data_[i] = other[i];
    }

    return *this;
  }

private:
  void alloc(std::size_t n) {
    delete[] data_;
    data_ = new Allocated[n];
    size_ = n;
  }

  Type *data_;
  std::size_t size_;
};

template<typename T, typename A>
std::ostream &operator<<(std::ostream &out, SerializableArray<T, A> const &s) {
  out << s[0];
  for(std::size_t i = 1; i < s.size(); ++i) {
    out << ',' << s[i];
  }

  return out;
}

int main() {
  SerializableArray<int>   s1(10);
  SerializableArray<short> s2;

  for(std::size_t i = 0; i < s1.size(); ++i) {
    s1[i] = i;
  }

  s2 = s1;

  std::cout << s1 << std::endl;
  std::cout << s2 << std::endl;
}



Bearbeitung:

Destruktor eingefügt, um der Speicherleckerei ein Ende zu bereiten.


--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra

Dieser Post wurde am 03.02.2009 um 23:08 Uhr von 0xdeadbeef editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
03.02.2009, 22:59 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


okay das schaut ganz gut aus joa.

Hab nur jetzt ein seltsames Problem:


C++:

const A a1;
A a2;

a2 = a1;



dafür wird mein operator= nicht aufgerufen?!? sondern a2.data wird einfach die gleiche speicheradresse wie a1.data zugewiesen, was natürlich dann kracht sobald a2 zerstört wird bzw a1 zerstört wird und a2 weitergenutzt werden soll
--
class God : public ChuckNorris { };

Dieser Post wurde am 03.02.2009 um 23:00 Uhr von FloSoft editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
03.02.2009, 23:09 Uhr
0xdeadbeef
Gott
(Operator)


In der Form sollte er eigentlich aufgerufen werden. Anders wäre das u.U. bei

C++:
A a2 = a1;


Zeig mal deinen Code her, das kann ich so nicht beantworten.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
03.02.2009, 23:28 Uhr
FloSoft
Medialer Over-Flow
(Administrator)



C++:
template ....
class SerializableArray usw
{
  template<typename T, typename A>
  SerializableArray &operator=(SerializableArray<T, A> const &other) {
    alloc(other.size());

    for(std::size_t i = 0; i < size(); ++i) {
      data_[i] = other[i];
    }

    return *this;
  }
};

class A
{
};

class B : public SerializableArray<A>
{
};

class C
{
  B _b;

  void function(const B &b)
  {
    _b = b; // hier wird nicht der operator aufgerufen
  }
};


--
class God : public ChuckNorris { };

Dieser Post wurde am 03.02.2009 um 23:28 Uhr von FloSoft editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
03.02.2009, 23:46 Uhr
0xdeadbeef
Gott
(Operator)


Baaaah, ja, ja, logisch. Du läufst da in eine der Fallen von C++ - wenn kein "copy assignment operator" deklariert ist, wird implizit einer definiert. Das bedeutet, du musst explizit einen deklarieren - dafür würde es sich wohl lohnen, das Kopieren in eine Funktionsvorlage auszulagern, etwa so:

C++:
#include <cstddef>
#include <iostream>

template<typename Type, typename Allocated = Type>
class SerializableArray {
public:
  SerializableArray()              : data_(NULL), size_(0) { }
  SerializableArray(std::size_t n) : data_(NULL), size_(0) { alloc(n); }

  ~SerializableArray() { delete[] data_; }

  std::size_t size() const { return size_; }

  Type       &operator[](std::size_t index)       { return data_[index]; }
  Type const &operator[](std::size_t index) const { return data_[index]; }

  template<typename T, typename A>
  SerializableArray &operator=(SerializableArray<T, A> const &other) {
    return copy(other);
  }

  SerializableArray &operator=(SerializableArray const &other) {
    return copy(other);
  }

private:
  template<typename T, typename A>
  SerializableArray &copy(SerializableArray<T, A> const &other) {
    alloc(other.size());

    for(std::size_t i = 0; i < size(); ++i) {
      data_[i] = other[i];
    }

    return *this;
  }

  void alloc(std::size_t n) {
    delete[] data_;
    data_ = new Allocated[n];
    size_ = n;
  }

  Type *data_;
  std::size_t size_;
};

template<typename T, typename A>
std::ostream &operator<<(std::ostream &out, SerializableArray<T, A> const &s) {
  out << s[0];
  for(std::size_t i = 1; i < s.size(); ++i) {
    out << ',' << s[i];
  }

  return out;
}

int main() {
  SerializableArray<int>   s1(10), s3;
  SerializableArray<short> s2;

  for(std::size_t i = 0; i < s1.size(); ++i) {
    s1[i] = i;
  }

  s2 = s1;
  s3 = s1;

  std::cout << s1 << std::endl;
  std::cout << s2 << std::endl;
}


--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
009
04.02.2009, 09:51 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


au, joa stimmt ich bin ein volldepp joa habs im moment dann nun eben mit ner copy-methode gelöst, aber so isses natürlich deutlich praktischer
--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: