简体   繁体   中英

Calling a constructor in C++

I am just starting out with C++. I have a class ourVector and within that class I have a constructor that is named ourVector() as well and it includes the initializations of variables. I need these variables to reset with every loop in main, but I can't figure out how to call the constructor in main.

class ourVector
    ourVector()
        {
            vectorCap = 20;
            vectorSize = 0;
        }

In main my class object is called ourVector vectorTest;

I just would like to figure out how to call ourVector() without getting an error so I can place it at the end of my loop in main to clear and re-initialize the variables.

Any help would be greatly appreciated.

Thank you!

Usually when you find yourself doing things like this it's a sign that maybe there's a more semantically appropriate way to structure your code (ie make the code structure more closely represent your intent).

In your case, ask yourself why you need to reset the value every time through the loop. It seems like you are just using your object to hold some intermediate data on each iteration through the loop, and you aren't concerned about the values outside of the loop (but if you are, you want something like riderBill's answer ). So really, your ourVector instance is only useful within the scope of that loop.

So make your code structure reflect that:

int main () {
    ...
    while (...) { // <- this represents your loop

        ourVector v; // <- each time through, 'v' is constructed

        ... // <- do whatever with 'v' here

    } // <- that 'v' goes away when it goes out of scope
    ...
}

In other words, just declare it in the loop, where it belongs. Semantically this makes sense (it represents how and where you're actually using the object), and it does what you want without modification to your ourVector .

In general, as a beginner's rule of thumb, try to declare variables in the tightest scope possible that still works for your code.

The constructor is only called when instantiating an object; you cannot explicitly call it to reinitialize your variables. But you can call public member setter function(s) from the constructor. Then you can call the setter function(s) again from within your loop.

class ourVector
{  int              vectorCap      ;
   int const defaultVectorCap  = 20; // No magic numbers!
   int              vectorSize     ;
   int const defaultVectorSize =  0;
   int       roomToGrow            ; // To illustrate a point about setters.
public:
   // Constructors
   ourVector() // Use this constructor if you don't know the proper initial values
               // (you probably always do or never do). 
   {  setVectorCap (defaultVectorCap );
      setVectorSize(defaultVectorSize);
   } // End of default constructor

   ourVector(   int vecCap, int vecSize)  // Lining stuff up improves readability
   {  setVectorCap (vecCap             ); // (e.g. understanding the code and
      setVectorSize(           vecSize ); // spotting errors easily).
                                          // It has helped me spot and avoid
                                          // bugs and saved me many many hours.
                                          // Horizontal white space is cheap!
                                          // --Not so forvertical white space IMHO.

   // Setters
   void setVectorCap(int vecCap)
   {  vectorCap        = vecCap;
      // I might need this internally in the class.
      // Setters can do more than just set a single value.
      roomToGrow = vectorCap - vectorSize;
   } // End of setVector w/ parameter

   void setVectorSize(int vecSize)
   {  vectorSize        = vecSize;
      roomToGrow = vectorCap - vectorSize; // Ok, redundant code.  But I did say
                                           // "As much as practical...."
   } // End of setVectorCap w/ parameter

   void setVectorSize()  // Set to default
   {  // Don't just set it here--leads to poor maintainability, i.e. future bugs.
      // As much as practical, redundant code should be avoided.
      // Call the setter that takes the parameter instead.
      setVectorSize(defaultVectorSize);
   } // End of setVectorSize for default size

   void setVectorCap()  // Set to default
   {  setVectorCap (defaultVectorCap );
   } // End of setVectorCap for default size

}; // End of class ourVector
#include <cstdio>
#include <cstdlib>
#include "ourVector.hpp"

int main(int argc, char *argv[]);
void doSomething(ourVector oV  );

int main(int argc, char *argv[])
{  ourVector oV;
   // Or, if you want non-default values,
 //int mySize =  2;
 //int myCap  = 30;
 //ourVector(mySize, myCap);

   for (int i = 0; i<10; i++)
   {  // Set fields to original size.
      oV.setVectorSize();
      oV.setVectorCap ();
      // Or
      //oV.setVectorSize(mySize);
      //oV.setVectorCap (myCap );

      // Whatever it is your are doing
      // ...
  }

   // Do whatever with your vector.  If you don't need it anymore, you probably should
   // have instantiated it inside the for() block (unless the constructor is
   // computationally expensive).
   doSomething(oV);
   return 0;
} // End of main()

void doSomething(ourVector oV) {}

This code works:

class ourVector
{
public:
    ourVector() : vectorCap(20), vectorSize(0) { };

    ourVector(int c, int s) : vectorCap(c), vectorSize(s) { };

    void setVCap(int v)
    {
        vectorCap = v;
    }

    void setVSize(int v)
    {
        vectorSize = v;
    }

    int getVCap()
    {
        return vectorCap;
    }

    int getVSize()
    {
        return vectorSize;
    }

    void print()
    {
        std::cout << vectorCap << ' ' << vectorSize << '\n';
    }

private:
    int vectorCap;
    int vectorSize;
};

int main()
{
    ourVector vectorTest(5,5);
    vectorTest.print();

    vectorTest.setVCap(6);
    vectorTest.setVSize(6);
    vectorTest.print();

    std::cout << vectorTest.getVCap() << ' ' << vectorTest.getVSize() << '\n';

    vectorTest = ourVector();
    vectorTest.print();
}

The ourVector() : vectorCap(value), vectorSize(value) { }; parts are the initializers. The vectorCap(value) part sets vectorCap to value ; the { } section is an empty method, use this to do any calculations and verifications you need. The SetVCap(int) and SetVSize(int) methods can be called to change the values of vectorCap and vectorSize , respectively. getVCap() and getVSize() return the values of vectorCap and vectorSize respectively.

In my example, you do not need to validate the code, so the initializers ourVector() : vectorCap(value), vectorSize(value) { }; work perfectly fine. If you need to validate the input, you may wish to call the assignment functions from the initializer so you only need to implement the validation once, which makes debugging easier. To do this, just replace the constructors with these constructors. Now you need only validate the input in one place:

ourVector()
{
    setVCap(20);
    setVSize(0);
}

ourVector(int c, int s)
{
    setVCap(c);
    setVSize(s);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM