0

That question title is a mouthful. Basically, I am creating a hash table structure that uses doubly linked lists within a vector. Everything works fine when I create the object using my overloaded constructor, but using the default constructor causes the state of the object to go funky after returning to main.

My constructors:

    HashTable::HashTable()
    {
            HashTable(53);
    }

    HashTable::HashTable(int tableSize)
    {
            currentSize = tableSize;
            table.resize(tableSize);
    }

Setting breakpoints after creating an object

    HashTable ht(size); //this works
    HashTable ht;       //this does not work

Stepping through the code I see that it calls the overloaded constructor fine, but after returning to main and then attempting to use the table (when using default constructor only), the vector's size and the variable currentSize have gone awry.

After creating object, before returning to main:

currentSize = 53
table [size] = 53, [capacity] = 53, empty linked lists fill the vector

When calling ht.hash(value) in main, the object now has:

currentSize = -858993460
table [size] = 0, [capacity] = 0, linked lists obviously gone.

What would cause the vector to reset itself to 0 and my private int currentSize to go funky, especially since the code paths both work through HashTable(int tableSize)?

randomusername
  • 107
  • 2
  • 10
  • 1
    `HashTable(53);` this does not delegate to another constructor. IIRC it creates a temporary. In C++11, you can delegate to another constructor via `HashTable::HashTable() : HashTable(53) {}` (search for *delegating constructors* and/or *member initializer list*). – dyp Apr 12 '14 at 22:42
  • @dyp - Thank you! `this->HashTable::HashTable(53);` or the initializer list worked great. – randomusername Apr 12 '14 at 22:51
  • `this->HashTable::HashTable(53);` [shouldn't work either inside the function body](http://coliru.stacked-crooked.com/a/93a68f895ed0e74c) o.O A constructor isn't a normal function that you can call directly. – dyp Apr 12 '14 at 23:20
  • @dyp, I'm simply calling my overloaded constructor from my default constructor. – randomusername Apr 24 '14 at 05:59
  • You could probably dispense with the default constructor and just give `tableSize` a default value - `HashTable::HashTable(int tableSize = 53)`. Unless there are other specific reasons you've done it that way... – twalberg Apr 24 '14 at 16:21
  • twalberg, this was a requirement for an assignment - having a default constructor set the size to a prime number, and an overloaded that allows the user to set the size manually. I was attempting to keep a single code path with the constructors; however, as @dyp pointed out, not all compilers are happy with the way I accomplished it. – randomusername Apr 28 '14 at 03:32

1 Answers1

0

@dyp Pointed me in the right direction.

HashTable(53); was creating a temporary local object - not setting the object in main to my desired size of 53.

To call the overloaded constructor on my object in main rather than create a temporary object, this->HashTable::HashTable(53); worked (in Visual Studio) to force the overloaded constructor to be called on my calling object.

EDIT: gcc compiler forbids this, and this is generally considered bad practice, whether your compiler allows it or not.

An initializer list as HashTable::HashTable() : HashTable(53) {} is considered to be the correct way to accomplish what I was trying to do.

randomusername
  • 107
  • 2
  • 10
  • *"and is a bit cleaner."* Not just *a bit*. I'd really like to know how you made your compiler compile [something like `this->HashTable::HashTable(53);`](http://coliru.stacked-crooked.com/a/d55eafe2cda246d7) since C++ forbids you to call a constructor directly. The version `HashTable::HashTable() : HashTable(53) {}` is valid C++11, the feature is called *delegating constructor*. – dyp Apr 24 '14 at 18:30
  • Hmm. I've read that C++ forbids a user calling a constructor: `Foo f; f.Foo();` - perhaps I need to review the standard when declaring methods though, as I haven't seen anything explicitly saying you cannot within the class declaration have a constructor call an overloaded constructor. VS has no problem with my constructor declaration, so I'm sure it's assembling differently than your gcc example. Then again, I'm not calling `Foo f; f.Foo()`, I simply have the option between `Foo f; and Foo f(int);`. – randomusername Apr 28 '14 at 03:03