Thread: Confused about constructors

  1. #1
    Registered User
    Join Date
    Sep 2007
    Posts
    36

    Confused about constructors

    I am trying to figure out how to modify this program so the file is read from the constructor:

    Code:
    #include <iostream> 
    #include <string> 
    #include <fstream> 
    #include <vector>
    using namespace std; 
    
    
    class Scramble { 
          private: 
                   vector<string> _word;
                   bool Check (string T, string S); 
          public: 
                  Scramble(vector<string> words){  
                  _word=words; 
                  
    } 
    void Descramble (string Scrambled); 
    }; 
    //******************************************
    void Scramble::Descramble(string Scrambled)
    { 
          bool flag=false; 
          for(int i=0;i<_word.size();i++)
          { 
                  if(_word[i].size()==Scrambled.size())
                  {
                       if(Check(Scrambled,_word[i])) 
                       {
                            cout << "The word is: " << _word[i]<< endl; 
                            flag=true;}
                  }
          }
          if (!flag)
          {
                  cout<< "The word: " << Scrambled <<" is not found"<< endl; 
                  return;
          }
    }
    //******************************************
    bool Scramble::Check(string T, string S)
    { 
          int n=T.size(); 
          int Found=0; 
          string temp=S; 
          for (int i=0; i<n; i++) 
          { 
                  bool flag = true; 
                  for (int j=0; j < n && flag;j++) 
                  if(T[i]== temp[j])
                  { 
                       temp[j]=' ';
                       flag=false;Found ++;
                  } 
          }
          if (Found==n)
                  return true; 
          else 
                  return false;
    } 
    //******************************************
    int main(){ 
          cout << "Welcome to the Scramble Game!\n\n";
          while (true)
          {
                  int play;
                  cout << "\nWould you like to play? \nEnter 1 for Yes or 2 for No:\n";
                  cin >> play;
                  if (play==1)
                  {
                       cout <<"\nPlease enter the scrambled word: ";
                       string Scrambled ;
                       cin >> Scrambled; 
                       ifstream file("dictionary.txt");
                   if(!file)
                       {
    	                    cout <<"\nError! The file couldn't be opened\n";
                       }
                        vector<string> word_list;
                       string word;
                       while(file >> word)
    	               {
                            word_list.push_back(word);
                       }
                           Scramble test(word_list); 
                       test.Descramble(Scrambled);
                       file.close();
                       cin.get(); cin.get();
                      
                      
                  
                  } 
                  else if (play==2)
                  {
                       cout << "\n\nGoodbye!\n\n";
                       cin.get(); cin.get();
                       return 0;
                  }
                  else
                  {
                       cout << "\nInvalid entry. Try again.\n\n";
                       cin.get(); cin.get();
                  }
          }
    }
    Would I just move the code for the "play" option to the Scramble class?

  2. #2
    Captain - Lover of the C
    Join Date
    May 2005
    Posts
    341
    This code would need to be in the constructor and you would need to pass the filename to it.
    Code:
    ifstream file("dictionary.txt");
    if(!file)
    {
        cout <<"\nError! The file couldn't be opened\n";
    }
    vector<string> word_list;
    string word;
    while(file >> word)
    {
        word_list.push_back(word);
    }
    Don't quote me on that... ...seriously

  3. #3
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    The problem with adding that code to the constructor is it makes it difficult to return an error. You have to either throw an exception (in which case the class object is never created), or set a member variable to indicate that initialization failed and hope the creator of the class checks that member before using the class.

    It would be better to add the code to a new member function which could return an error if the file failed to open.

  4. #4
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    I think it's generally better to let the constructor open the file. You need to ask, does the class make any sense if the file cannot be opened? In this case, no, because then you have no dictionary to check against.

    So if the file fails to open in the constructor, you can throw an exception. You can also indicate error with a flag, or just continue with an empty dictionary. The exception might be the best choice, since the dictionary file should really always be there, but if you haven't learned exceptions yet then perhaps either of the other two options or something else would be fine.

  5. #5
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    I think it's generally better to let the constructor open the file. You need to ask, does the class make any sense if the file cannot be opened? In this case, no, because then you have no dictionary to check against.
    In that case, one could attempt to open the file. If successful, one then goes on to construct the object, passing the input/output stream opened to the constructor, and then work with the object. Otherwise, one would handle the error.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  6. #6
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    Agreed. There are many options. I guess I'm just against having a separate member function to handle the file. The class should be usable once it's been constructed rather than having a second function that must be called to initialize.

  7. #7
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by Daved View Post
    Agreed. There are many options. I guess I'm just against having a separate member function to handle the file. The class should be usable once it's been constructed rather than having a second function that must be called to initialize.
    In other words, "RAII, baby."

  8. #8
    Registered User
    Join Date
    Sep 2007
    Posts
    36
    Thanks for all the answers, but I need a little more help witht the actual syntax. If I try Brad's suggestion and move that piece of code, how do I keep the program flowing? Do I call the constructor like a function?

  9. #9
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Do I call the constructor like a function?
    You would write something like:
    Code:
    Scramble scramble("dictionary.txt");
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  10. #10
    Registered User
    Join Date
    Sep 2007
    Posts
    36
    When I try "Scramble scramble("dictionary.txt");"

    I get these errors :

    no matching function for call to `Scramble::Scramble(const char[15])'

    candidates are: Scramble::Scramble(const Scramble&)

    Scramble::Scramble(std::vector<std::string, std::allocator<std::string> >)

  11. #11
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Read Brad0407's suggestion again: "This code would need to be in the constructor and you would need to pass the filename to it."
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  12. #12
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    In other words, you need to create a new constructor that takes a filename.

  13. #13
    Registered User
    Join Date
    Sep 2007
    Posts
    36
    I know this probably sounds stupid, but how do I pass the filename to the constructor? I can't seem to find any examples! And why do I need 2 constructors? Can't I just add parameters to the one I am already using?

  14. #14
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Can't I just add parameters to the one I am already using?
    You can do that too, of course. It may even be better.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  15. #15
    Registered User
    Join Date
    Sep 2007
    Posts
    36
    Ok, so how do I go about that? What would that parameter be? And why couldn't I just open the file in the constructor rather than passing it from main and then opening it?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. still confused with constructors and private data members
    By freddyvorhees in forum C++ Programming
    Replies: 2
    Last Post: 07-26-2008, 09:29 AM
  2. Copy constructors; Best practices (and private)
    By Mario F. in forum C++ Programming
    Replies: 15
    Last Post: 06-23-2006, 04:42 PM
  3. constructors, arrays, and new
    By Thantos in forum C++ Programming
    Replies: 6
    Last Post: 05-30-2004, 06:21 PM
  4. confused.. in selecting my line of deapth
    By jawwadalam in forum A Brief History of Cprogramming.com
    Replies: 4
    Last Post: 05-04-2003, 01:21 PM
  5. Copy constructors and private constructors
    By Eibro in forum C++ Programming
    Replies: 5
    Last Post: 11-24-2002, 10:16 AM