⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 7store.html

📁 C ++ in action
💻 HTML
字号:
<html>
<head>
	<title>Store</title>
    <meta  name="description" content="Implementation of variable store in C++">
    <meta name="keywords" content="calculator, memory, symbol, variable, storage, implementation">
	<link rel="stylesheet" href="../../rs.css">
</head>

<body background="../../images/margin.gif" bgcolor="#FFFFDC">

<!-- Main Table -->
<table cellpadding="6">
    <tr>
    <td width="78">
	&nbsp;
	<td>


<h3>Store</h3>
<p class=topics>Forward declarations.
<p>Our calculator can deal with symbolic variables. The user creates a variable by inventing a name for it and then using it in arithmetic operations. Every variable has to be initialized梐ssigned a value in an assignment expression梑efore it can be used in evaluating other expressions. To store the values of user defined variables our calculator will need some kind of &quot;memory.&quot; We will create a class <var>Store</var> that contains a fixed number, <var>size</var>, of memory cells. Each cell can store a value of the type double. The cells are numbered from zero to <var>size</var>-1. Each cell can be in either of two states梪ninitialized or initialized.
<!-- Code --><table width="100%" cellspacing=10><tr>	<td class=codetable>

<pre>enum { stNotInit, stInit };

</pre></table><!-- End Code --><p>The association between a symbolic name梐 string梐nd the cell number is handled by the symbol table. For instance, when the user first introduces a given variable, say <i>x</i>, the string &quot;x&quot; is added to the symbol table and assigned an integer, say 3. From that point on, the value of the variable <i>x</i> will be stored in cell number 3 in the <var>Store</var> object.

<p>We would also like to pre-initialize the symbol table and the store with some useful constants like <i>e</i> (the base of natural logarithms) and <i>pi</i> (the ratio of the circumference of a circle to its diameter). We would like to do it in the constructor of <var>Store</var>, therefore we need to pass it a reference to the symbol table. Now here抯 a little snag: We want to put the definition of the class <var>Store</var> in a separate header file, <b><i>store.h</i></b>. The definition of the class <var>SymbolTable</var> is in a different file, <b><i>symtab.h</i></b>. When the compiler is looking at the declaration of the constructor of <var>Store</var>
<!-- Code --><table width="100%" cellspacing=10><tr>	<td class=codetable>

<pre>    Store (int size, SymbolTable &amp; symTab);

</pre></table><!-- End Code --><p>it has no idea what <var>SymbolTable</var> is. The simple-minded solution is to include the file <b><i>symtab.h</i></b> in <b><i>store.h</i></b>. There is nothing wrong with doing that, except for burdening the compiler with the processing of one more file whenever it is processing <b><i>symtab.h</i></b> or any file that includes it. In a really big project, with a lot of header files including one another, it might become a real headache. If you are using any type of dependency checker, it will assume that a change in <b><i>symtab.h</i></b> requires the recompilation of all the files that include it directly or indirectly. In particular, any file that includes <b><i>store.h</i></b> will have to be recompiled too. And all this unnecessary processing just because we ed to let  the compiler know that <var>SymbolTable</var> is a name of a class? Why don抰 we just say that? Indeed, the syntax of such a <b><i>forward declaration</i></b> is:
<!-- Code --><table width="100%" cellspacing=10><tr>	<td class=codetable>

<pre>class SymbolTable;

</pre></table><!-- End Code --><p>As long as we are <i>only</i> using pointers or references to <var>SymbolTable</var>, this will do. We don抰 need to include <b><i>symtab.h</i></b>. On the other hand, a forward declaration would not be sufficient if we wanted to call any of the methods of <var>SymbolTable</var> (including the constructor or the destructor) or if we tried to embed or inherit from <var>SymbolTable</var>. 
<!-- Code --><table width="100%" cellspacing=10><tr>	<td class=codetable>

<pre>class SymbolTable; // forward declaration

class Store
{
public:
    Store (int size, SymbolTable &amp; symTab);
    ~Store ()
    {
        delete []_cell;
        delete []_status;
    }
    bool IsInit (int id) const
    {
        return (id &lt; _size && _status [id] != stNotInit);
    }
    double Value (int id) const
    {
        assert (IsInit (id));
        return _cell [id];
    }
    void SetValue (int id, double val)
    {
        if (id &lt; _size)
        {
            _cell [id] = val;
            _status [id] = stInit;
        }
    }
private:
    int             _size;
    double        * _cell;
    unsigned char * _status;
};
</pre></table><!-- End Code -->
<var><p>Store</var> contains two arrays. The array of cells and the array of statuses (initialized/uninitialized). They are initialized in the constructor and deleted in the destructor. We also store the size of these arrays (it's used for error checking). The client of <var>Store</var> can check whether a given cell has been initialized, get the value stored there, as well as set (and initialize) this value.

<!-- Sidebar -->
<table width="100%" border=0 cellpadding=5><tr>
<td width=10>
<td bgcolor="#cccccc" class=sidebar>

<p>Why am I using two arrays instead of a single array of two-field objects? I could have defined a class <var>Cell</var>

<!-- Code --><table width="100%" cellspacing=10><tr>	<td class=codetable>
<pre>class Cell
{
    // 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -