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 Offline
    V Offline
    VeganFanatic
    wrote on last edited by
    #1

    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 C 2 Replies 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

      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