Sign in to follow this  
paintstripper88

Class Instances

Recommended Posts

I am having trouble creating new instances of classes. This is the code for my class:

#include <string> 
#include <iostream>
#include <fstream>

using namespace std;
 
class NewReference
{
public:
  NewReference()
  {
  }

  virtual ~NewReference()
  {
  }

  virtual void CreateNewReference() const = 0;
  //virtual void DrawFill() const = 0;
};

class Book : public NewReference
{
public:
void set_author(string theauthor);
string Book::get_author();
  Book()
  {
  }
  
virtual ~Book()
  {
  }

  virtual void CreateNewReference() const
  {
	cout << "TESTTESTEST" << endl;
  }
private:
	string Author;



};

void Book::set_author(string theauthor)
{
	Author = theauthor;
}

string Book::get_author()
{
	return Author;
}


And this is the code that I am using to create a new instance of the Book class.
Book bk;
bk.CreateNewReference();

The above code works fine, but how would I create an array of the book class, so that I can use bk like this: bk[1].CreateNewReference(); Or with a loop: bk[i].CreateNewReference(); Any help is appreciated.

Share this post


Link to post
Share on other sites
Dranith    504
As long as your class has a default constructor (as yours does), you can declare an array of classes in the same way you declare an array of other variable types:

Book bk[size];

for example. Then you can just index into this array as usual, bk[1] .. or in a loop as bk[i].

If you don't want a static array, then again, it is the same as creating dynamic arrays of built in types:

Book* bk2 = new Book[size];

Just remember to use the array delete (delete[]) when freeing the memory.

Alternatively, you could just create a vector<Book> and let it manage the memory and resizing for you. If you want a book array of a specific size, you can just call vector::resize, or specify the size at time of construction.

The vector option is probably the 'best' as it has both flexibility and ease of use. The only downside is it requires some knowledge of the vector template.

Edit: Minor wording changes

Share this post


Link to post
Share on other sites
Zahlman    1682
- Don't write constructors that don't do anything. Rely on the compiler-generated version. Writing it yourself adds more work that won't change the meaning of the code, adds extra stuff to read when trying to understand the class, and introduces the potential for silly and annoying compile errors (e.g. due to declaring it and forgetting to define it). Most constructors in C++ can have an empty body (with all work being done in the initialization list). You only need to specify a no-argument constructor if (a) the class *should* be constructible from no arguments AND (b) the class *also* defines a constructor requiring arguments. (Note here that "no-argument" means *can* be used with no arguments; consider the effect of default arguments.)

- Don't write empty destructors, *except* to create the virtual destructor of the base class. Same reasoning as above.

- What is 'CreateNewReference' supposed to *do*? It sounds like it's supposed to, well, instantiate the class. But that's what constructors are for. There do exist valid reasons for making such functions (often referred to as "factory" functions), but (a) they need to return something (typically a smart pointer to a dynamically allocated instance of the class), and (b) they should normally be static (because it doesn't make sense to require that you already have an instance of the class in order to create one; that's a chicken-and-egg problem). "clone" functions are of course a different story.

- For that matter, what is a "NewReference"? I.e., why have you chosen that as the name of your base class? If you asked me what a book is, I can tell you I would never in a million years think to answer "well, it's a kind of new reference".

- Avoid set and get methods, especially when both exist for the same member. If something only needs to be set in order to initialize the object, then again, that's a job for the constructor. (This is the case, when you think about it, for a surprising number of classes in real-world code that abuse setters.) These pairs of functions generally don't improve the encapsulation, because even though you are "free" to rename the underlying member or add sanity checks or whatever, (a) in the real world, those things tend not to be done - ever; and (b) the user of the class is still forced to think in terms of "manipulating a data member", even if that data member isn't really there. This is, in *most* cases, not a meaningful interface abstraction. (Always-or-never rules are rarely correct ;) )

- To create the array, just declare it. If it's a local (static) array (i.e. of known size), then you do it just like you would with a primitive type; i.e., just like you can write 'int foo[5];' or 'int foo[] = { 1, 2, 3, 4, 5 };', you can write 'Book foo[5];' or 'Book foo[] = { Book(), Book(), Book(), Book(), Book() };'. But note that you can't store Books (by value) in an array of NewReferences, because they don't "fit" into the "slots" of the array.

Share this post


Link to post
Share on other sites
The NewReference class is named 'NewReference', because I am creating a program that formats referencing files for a certain end text referencing format, in this case APA 5th.

Thanks for the advice, using the constructor instead of set functions will help a lot.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this