Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
CODE PROJECT For Those Who Code
  • Home
  • Articles
  • FAQ
Community
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. inheriting std::vector

inheriting std::vector

Scheduled Pinned Locked Moved C / C++ / MFC
databasegraphicsquestion
12 Posts 5 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • V VeganFanatic

    a while ago I wrote a vector template to assist in a project, it works OK. I was considering the effect inheriting the std::vector and make all of the functionality available and simply attach my new functionality on top of that. Is this practical? Here is the vector as it stands today. template <class base> class vector { public: std::vector<base> data; friend class matrix<base>; vector operator+(const vector &that) { // parallelogram law vector ret; assert(this->data.size() == that.data.size()); ret.resize(this->data.size()); #pragma omp parallel for for (int i = 0; i < this->data.size(); i++) ret.data[i] = this->data[i] + that.data[i]; return ret; } vector operator-(vector that) { // parallelogram law vector ret; assert(this->data.size() == that.data.size()); ret.resize(this->data.size()); #pragma omp parallel for for (int i = 0; i < this->data.size(); i++) ret.data[i] = this->data[i] - that.data[i]; return ret; } vector operator* (base &that) { // scalar product vector ret; ret.resize(this->data.size()); #pragma omp parallel for for (int i = 0; i < this->data.size(); i++) ret.data[i] = this->data[i] * that; return ret; } double operator* (vector &that) { // dot / inner product double ret; #pragma omp parallel for for (int i = 0; i < this->data.size(); i++) ret += this->data[i] * that.data[i]; // sum of products of complex numbers is real return ret; } vector operator/ (base &that) { // scalar division vector ret; ret.resize(this->data.size()); #pragma omp parallel for for (int i = 0; i < this->data.size(); i++) ret.data[i] = this->data[i] / that; return ret; } vector operator= (vector &that) { // assignment operator for (int i=0; i < that.data.size(); i++) this->data[i] = that.data[i]; return *this; } base& operator[] (size_t index) { return this->data[index]; } bool operator== (vector &that) { bool temp = true; for (int i=0; i < that.data.size(); i++) if (this->data[i] != that.data[i]) temp = false; return temp; } // the norm is the vector length base norm(void) { base result = (base)0.0; #pragma omp parallel for for (int i = 0; i < this->data.size(); i++) { result += this->data[i] * this->data[i]; // sum of products of complex numbers is real } retu

    A Offline
    A Offline
    Aescleal
    wrote on last edited by
    #2

    The general concensus is don't inherit from an STL collection - they're not designed for it. The two ways I'd recommend going about extending an STL collection is either bundle it up in another class (which you've done) OR just write free functions to do the extended functionality. From your example it looks like you want a geometric vector and not a collection of doodads that might or might not have some geometric relationship. Incidentally if you want to continue using containment the way you have make the std::vector private. You really don't want a class exposing data through it's public interface, it's really hard to test and some idiot will maul it for you - even if that idiot turns out to be you several months down the line when you've forgotten what you did. Cheers, Ash

    V 1 Reply Last reply
    0
    • V VeganFanatic

      a while ago I wrote a vector template to assist in a project, it works OK. I was considering the effect inheriting the std::vector and make all of the functionality available and simply attach my new functionality on top of that. Is this practical? Here is the vector as it stands today. template <class base> class vector { public: std::vector<base> data; friend class matrix<base>; vector operator+(const vector &that) { // parallelogram law vector ret; assert(this->data.size() == that.data.size()); ret.resize(this->data.size()); #pragma omp parallel for for (int i = 0; i < this->data.size(); i++) ret.data[i] = this->data[i] + that.data[i]; return ret; } vector operator-(vector that) { // parallelogram law vector ret; assert(this->data.size() == that.data.size()); ret.resize(this->data.size()); #pragma omp parallel for for (int i = 0; i < this->data.size(); i++) ret.data[i] = this->data[i] - that.data[i]; return ret; } vector operator* (base &that) { // scalar product vector ret; ret.resize(this->data.size()); #pragma omp parallel for for (int i = 0; i < this->data.size(); i++) ret.data[i] = this->data[i] * that; return ret; } double operator* (vector &that) { // dot / inner product double ret; #pragma omp parallel for for (int i = 0; i < this->data.size(); i++) ret += this->data[i] * that.data[i]; // sum of products of complex numbers is real return ret; } vector operator/ (base &that) { // scalar division vector ret; ret.resize(this->data.size()); #pragma omp parallel for for (int i = 0; i < this->data.size(); i++) ret.data[i] = this->data[i] / that; return ret; } vector operator= (vector &that) { // assignment operator for (int i=0; i < that.data.size(); i++) this->data[i] = that.data[i]; return *this; } base& operator[] (size_t index) { return this->data[index]; } bool operator== (vector &that) { bool temp = true; for (int i=0; i < that.data.size(); i++) if (this->data[i] != that.data[i]) temp = false; return temp; } // the norm is the vector length base norm(void) { base result = (base)0.0; #pragma omp parallel for for (int i = 0; i < this->data.size(); i++) { result += this->data[i] * this->data[i]; // sum of products of complex numbers is real } retu

      C Offline
      C Offline
      Chris Losinger
      wrote on last edited by
      #3

      it might work, but in general you should avoid inheriting directly from STL containers, if you can. the reason is that these containers do not have virtual destructors, and that may expose you to memory leaks. http://www.codeguru.com/forum/archive/index.php/t-267641.html[^]

      image processing toolkits | batch image processing

      V 1 Reply Last reply
      0
      • A Aescleal

        The general concensus is don't inherit from an STL collection - they're not designed for it. The two ways I'd recommend going about extending an STL collection is either bundle it up in another class (which you've done) OR just write free functions to do the extended functionality. From your example it looks like you want a geometric vector and not a collection of doodads that might or might not have some geometric relationship. Incidentally if you want to continue using containment the way you have make the std::vector private. You really don't want a class exposing data through it's public interface, it's really hard to test and some idiot will maul it for you - even if that idiot turns out to be you several months down the line when you've forgotten what you did. Cheers, Ash

        V Offline
        V Offline
        VeganFanatic
        wrote on last edited by
        #4

        I guess I will need to add more accessors then to make it resemble the std::vector My goal is to resemble the std::vector and bolt on some linear algebra

        http://www.contract-developer.tk

        1 Reply Last reply
        0
        • C Chris Losinger

          it might work, but in general you should avoid inheriting directly from STL containers, if you can. the reason is that these containers do not have virtual destructors, and that may expose you to memory leaks. http://www.codeguru.com/forum/archive/index.php/t-267641.html[^]

          image processing toolkits | batch image processing

          V Offline
          V Offline
          VeganFanatic
          wrote on last edited by
          #5

          I find that adding: template <class base> class vector : std::vector<base> does not seem to provide a great deal of change? So what impact if any does inheriting the object get me?

          http://www.contract-developer.tk

          C 1 Reply Last reply
          0
          • V VeganFanatic

            I find that adding: template <class base> class vector : std::vector<base> does not seem to provide a great deal of change? So what impact if any does inheriting the object get me?

            http://www.contract-developer.tk

            C Offline
            C Offline
            Chris Losinger
            wrote on last edited by
            #6

            VeganFanatic wrote:

            So what impact if any does inheriting the object get me?

            again, STL containers do not provide virtual destructors[^]

            image processing toolkits | batch image processing

            V 1 Reply Last reply
            0
            • C Chris Losinger

              VeganFanatic wrote:

              So what impact if any does inheriting the object get me?

              again, STL containers do not provide virtual destructors[^]

              image processing toolkits | batch image processing

              V Offline
              V Offline
              VeganFanatic
              wrote on last edited by
              #7

              Should I simply add more code and add formal constructors and destructors? Go for base* data construct instead?

              http://www.contract-developer.tk

              C 1 Reply Last reply
              0
              • V VeganFanatic

                Should I simply add more code and add formal constructors and destructors? Go for base* data construct instead?

                http://www.contract-developer.tk

                C Offline
                C Offline
                Chris Losinger
                wrote on last edited by
                #8

                VeganFanatic wrote:

                Should I simply add more code and add formal constructors and destructors?

                no matter what you do, because STL containers do not have virtual dtors, the destructor in your derived class will not be called. http://www.devx.com/tips/Tip/13509[^]

                image processing toolkits | batch image processing

                S 1 Reply Last reply
                0
                • C Chris Losinger

                  VeganFanatic wrote:

                  Should I simply add more code and add formal constructors and destructors?

                  no matter what you do, because STL containers do not have virtual dtors, the destructor in your derived class will not be called. http://www.devx.com/tips/Tip/13509[^]

                  image processing toolkits | batch image processing

                  S Offline
                  S Offline
                  Stephen Hewitt
                  wrote on last edited by
                  #9

                  This is only an issue if he deletes the object through the base class.

                  Steve

                  C 1 Reply Last reply
                  0
                  • S Stephen Hewitt

                    This is only an issue if he deletes the object through the base class.

                    Steve

                    C Offline
                    C Offline
                    Chris Losinger
                    wrote on last edited by
                    #10

                    well, i provided as many links to detailed explanations as i could stand to look up.

                    image processing toolkits | batch image processing

                    E 1 Reply Last reply
                    0
                    • C Chris Losinger

                      well, i provided as many links to detailed explanations as i could stand to look up.

                      image processing toolkits | batch image processing

                      E Offline
                      E Offline
                      Emilio Garavaglia
                      wrote on last edited by
                      #11

                      Chris, those links are "things to be noted" not "the Bible". The STL itself is designed by inheriting between classes that don't have virtual destructor. Think to iofstream versus istream and ostream STL containers don't have virtual destructors because they are designed to be non-polymophic and to exist into a closed scope. If you respect this, that means don't do things like (pseudocode)

                      vector* p = new myvector;
                      delete p; //worng: will destroy only "vector" not "myvector"

                      but just

                      {
                      myvector v;
                      //whatever you want with v, including vector functionality
                      }

                      you are in any case in a right position.

                      2 bugs found. > recompile ... 65534 bugs found. :doh:

                      C 1 Reply Last reply
                      0
                      • E Emilio Garavaglia

                        Chris, those links are "things to be noted" not "the Bible". The STL itself is designed by inheriting between classes that don't have virtual destructor. Think to iofstream versus istream and ostream STL containers don't have virtual destructors because they are designed to be non-polymophic and to exist into a closed scope. If you respect this, that means don't do things like (pseudocode)

                        vector* p = new myvector;
                        delete p; //worng: will destroy only "vector" not "myvector"

                        but just

                        {
                        myvector v;
                        //whatever you want with v, including vector functionality
                        }

                        you are in any case in a right position.

                        2 bugs found. > recompile ... 65534 bugs found. :doh:

                        C Offline
                        C Offline
                        Chris Losinger
                        wrote on last edited by
                        #12

                        i thought it would be better to tell the OP where to find relevant information, rather than to try explaining the entire topic and trying to find out which bits he needed to specifically worry about.

                        image processing toolkits | batch image processing

                        1 Reply Last reply
                        0
                        Reply
                        • Reply as topic
                        Log in to reply
                        • Oldest to Newest
                        • Newest to Oldest
                        • Most Votes


                        • Login

                        • Don't have an account? Register

                        • Login or register to search.
                        • First post
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • World
                        • Users
                        • Groups