Basically what I need to achieve is to create an array that inputs a puzzle from file. Problem is my previous attempt in last semester had the teachers jaw dropping from the amount of code lines I used... around 400+ in a couple of methods. So I'm trying to limit this and break it up as much as possible.
I have a class that mimics a 2d array, when I open the file on line 47 I create the object which is in essence a object that holds a pointer, the array has size of 0. If I then read in each line and pass to a function which deals with the current line, when a puzzle line is reached will I be able to effect the object which I pass by reference by stating it's new size or would I need to use assignment, and if I need to use assignment to copy the existing object from the new object with size say for example array[6 * 9], would the information I pass to the existing object still stay in scope until I reach EOF.
//=============================================//
void wordfinder::openFile()
{
string line="";
unsigned count=1;
ifstream ifs(filename.c_str());
if (! ifs.is_open())
{
cout << "Error: error opening file: " << filename << "\n";
cout << "Usage: a1 -f \'filename\'" << endl;
exit(1);
}
Array2D puzzle; // create object of 2dArray class
while (! ifs.eof())
{
getline(ifs,line);
processString(line,count,puzzle);
++count;
}
}
//=============================================//
void wordfinder::processString(string& line, unsigned line_count, Array2D& puzzle)
{
string tmp_line = line;
convert2Upper(tmp_line);
while(true)
{
if (isComment(line)) { }
elseif (isSize(tmp_line))
{
if (gotSize)
resetBools();
gotSize = parseSize(line, _row, _col);
}
elseif (isSearch(tmp_line))
{
if (gotWord)
resetBools();
gotWord = parseWord(line,_word);
}
else // is puzzle
{
if (gotSize && gotWord)
{
//<------------------------------
// here I simply give the object new array dimentions
// or create a new object and copy it over to
// the old one, then put the first row of
// characters into the first row of the array.
}
else
{
cout << "Error: line: " << line_count
<< " either don't have size or word, cannot process puzzle";
resetBools();
}
}
}
}
//=============================================//
I would love the object to go out of scope every time the puzzle is created, filled, solved and then output.... I just can't for the life of me figure out how to achieve that, and looking at my work from last semester was even worse, I had the object as a global object. So it didn't go out of scope until end of program. Which is probably while why there were a few subtle memory leaks.
The array class has both default ctor size 0, ctor with size arguments, copy ctor, overloaded assignment operator, and dtor.
I'm a beginner, so there's a big chance I misunderstood you, but wouldn't it be easier to just create 2D vector in your class and properly "push_back" values for each dimension? You can than save/get coordinates to/from 2 public variables (1 for each dimension) in your class object. And if you want to get the size of the puzzle, you can create two int-type functions, each returning size of each dimension's vector.
If i could use vector I wouldn't be creating a class that mimics a 2D array.
My question is regarding scope, and whether or not I'm doing this right.
I think it looks ok to me, but the processString method is still going to end up with about 80+ lines.
I only learned last week that dctors are called every time a block goes out of scope, I always thought it was when the class went out of scope.
I only learned last week that dctors are called every time a block goes out of scope
This is true for objects allocated locally on the stack. As is the case with your array here.
1 2 3 4 5 6 7 8 9
Array2D puzzle; // puzzle is put on the stack here
while (! ifs.eof())
{
getline(ifs,line);
processString(line,count,puzzle);
++count;
}
} // puzzle goes out of scope here, therefore the dtor is called here
If you want to increase the lifetime of the array, you need to give it broader scope.
I would put it in class scope of whatever class is the overall manager for the puzzle/program. Whether or not that is 'wordfinder' I couldn't say.
Afterall... logically if you want the array to have a lifetime equal to the life of the puzzle, then it makes sense to have the array owned by the puzzle. Or if this 'puzzle' array is the only object/class you have to represent the overall puzzle, then have it owned by whatever is driving the puzzle logic, or whatever is using the puzzle.
To get a better idea, why don't you give us a list of all the classes you have for this program and what each of them represents / does? That would make it easier to see where this array belongs.
main creates obj of chkArgs and checks cmd line args, creates obj of wordfinder and passes the filename of the puzzle to the ctor which is given by user in cmd line args. wordfinder, tries to open the file as seen in openFile() method above.
Then passes each line read inn from file to processString(). processString, calls many other methods depending on the line read in, checks for comments, puzzle size, etc.
The current scope of the object array2D named puzzle line 47 is pretty much the widest scope I guess, without making it a private member(global variable).
It was originally in the while not end of file block, however after I made the post realized that would reinitialize or recreate the object with the same name every time it read in a line from the file, so I moved it above the block.
When you say that's true for object created locally, do you mean opposed to created dynamically? Whats the difference? or what happens to objects dctor when created dynamically?
I'm at work right now so I can't give this a thorough go-over.
From what it sounds like, is main() is doing the work of managing the puzzle, and the other classes just do small part of it. Is that right?
If so, then logically main should own the puzzle. So that's where its scope should be.
When you say that's true for object created locally, do you mean opposed to created dynamically?
Locally created objects are put on the stack and are automaticaly destructed and destroyed when their scope ends.
Dynamically created objects are put on the heap and are NOT destructed or destroyed until you explicitly delete them. That is, they can have a lifetime longer than the scope in which they were created (but that doesn't always mean that's a good idea).
Example:
1 2 3 4 5 6 7 8 9 10
{
Myclass a; // ctor here
} // dtor here, ('a' goes out of scope)
Myclass* a;
{
a = new Myclass; // ctor here
} // nothing happens here
delete a; // dtor here
oh yeah I knew that *sort of*, that's a little different to how I interpreted it...
If you have the delete a; inside the dctor it is deleted much the same as the first block? at the end of block.
We are required to use a dynamic array and (std::nothrow), and my Array2D class does just that.
It's alright thanks anyway Disch, I think I'lll just write it all up and test it, then worry about design if I get any problems. I'm 99.9999% certain that last semester the subtle bugs I was getting in my program could have been scope issues, but I mostly get it now. Either that or my copy ctor, overloaded assignment operator are off.