| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 2683 人关注过本帖
标题:All about C++
取消只看楼主 加入收藏
kai
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:52
帖 子:3450
专家分:59
注 册:2004-4-25
收藏
得分:0 
谈到 namespace 的具体使用,分两步来谈。
1)声明或定义一个 namespace
2)  对某个namespace 下的变量或函数具体调用。

首先来谈第一点:
  下面具体来看两个 namespace 的声明(代码摘录于 C++ PrimerPlus, Fifth  Edition,  Page  426)
  namespace Jack
{
    double pail;            // variable declaration
    void fetch();           // function prototype
    intpal;               // variable declaration
    struct Well{ ... };     // structure declaration
}   
namespace Jill
{
    double bucket(double n){ ... } // function definition
    doublefetch;                 // variable declaration
    intpal;                      // variable declaration
    structHill{...};             // structure declaration
}   

Namespaces 可以像设置全局变量一样设置,namespaces  可以嵌套与其他  namespaces中,但是namespaces 不可以设置于某个某个块中,即不可以局部设置于某个函数块中或独立的设置于 两个花括号之中。也就是说,一个位于namespace  中的变量或函数在默认情况下具有外部连接能力(除非他被指定为  const)
此外,namespace 是开放的,也就是说,你可以在 namespace 的声明或定义之外,添加代码,即添加变量以及函数。
比如
namespace Jill
{
    char * goose(const char * );  // adds the name goose to the exiting list of names in Jill
}

通常的做法是我们将 namespace 的声明写入一个或多个头文件,将定义写入一个 cpp 或多个 cpp 文件

第二点, 对某个namespace 下的变量或函数具体调用:
最简单的做法是采用作用域操作符 ::
比如  Jack::pail = 12.34;   // use a variable
    Jill::Hill mole;      // create a type Hill structure
    Jack::fetch();        // use a function

此外必须提到的是  using Declarations and using Directives
由于使用作用域操作符的比较麻烦,因为它增加了你打字的工作,我想没几个人喜欢在每句cout 前增加 std:: 的。但是在某种情况下采用作用域的方法不可避免,这也是  姬老师 那个 抗议贴中提到的担心。 下面我也将提到。

  a) using Declarations - 对namespace 下的具体变量以及函数声明调用。如:using Jill::fetch;  // a using declaration
这样声明后,以后在程序中如出现 对变量 fetch 的操作将被认为是 Jill 那个namespace 下的 fetch, 如果在程序中Jill::fetch的作用域内再声明或定义同样名字的变量将被认为出错。下面的代码说明这个问题:
namespace Jill
{
    double bucket(double n){ ... } // function definition
    doublefetch;                 // variable declaration
    intpal;                      // variable declaration
    structHill{...};             // structure declaration
}   

char fetch;   // ok
int main()
{
    using Jill::fetch;    // put fetch into local namespace
    double fetch;         // Error! Already have a local fetch
   cin>>fetch;          // read a value into Jill::fetch
    cin>>::fetch;         // read a value into global fetch
   
    ......
    return 0;
}

与此相比, using directive 使得整个namespace 下的变量以及函数成为有效调用。

比如如果在程序中这样写:
using namespace Jack;
cin>>pail;
fetch();
那么这里的pail, fetch()  将被认为是 Jack  名字空间下的变量和函数。

现在来谈  姬老师  所担心的那个歧义性:
在使用了 using directives 以及  使用了 using declarations  之后,随之也带来一个问题,那就是歧义性问题。
比如如下代码:
using Jack::pal;
    using Jill::pal;
    pal = 4;          // which one? now have a conflict

但如果我们明确使用作用域符合,那么这样的歧义性就没有了。 如 Jill::pal= 4;  //  no conflict

下面摘入书上程序 listing 9.10,  listing 9.11 以及 listing 9.12, 让大家感受一下 namespace 在程序中的使用。

// namesp.h
// create the pers and debts namespaces
namespace pers
{
    const int LEN = 40;
    struct Person
    {
        char fname[LEN];
        char lname[LEN];
    };
    void getPerson(Person &);
    void showPerson(const Person &);
}

namespace debts
{
    using namespace pers;
    struct Debt
    {
        Person name;
        double amount;
    };
    void getDebt(Debt &);
    void showDebt(const Debt &);
    double sumDebts(const Debt ar[], int n);
}

// namesp.cpp -- namespaces
#include <iostream>
#include "namesp.h"

namespace pers
{
    using std::cout;
    using std::cin;
    void getPerson(Person & rp)
    {
        cout<<"Enter first name: ";
        cin>>rp.fname;
        cout<<"Enter last name: ";
        cin>>rp.lname;
    }

    void showPerson(const Person & rp)
    {
        std::cout<<rp.lname<<", "<<rp.fname;
    }
}

namespace debts
{
    void getDebt(Debt & rd)
    {
        using namespace pers;
        getPerson(rd.name);      // hier ist merkwuerdig
        std::cout<<"Enter debt: ";
        std::cin>>rd.amount;
    }

    void showDebt(const Debt & rd)
    {
        pers::showPerson(rd.name);     // hier ist merkwuerdig
        std::cout<<": $"<<rd.amount<<std::endl;
    }

    double sumDebts(const Debt ar[], int n)
    {
        double total = 0;
        for(int i = 0; i<n; i++)
            total += ar[i].amount;
        return total;
    }
}

// usenmsp.cpp -- using namespaces
#include <iostream>
#include "namesp.h"

void other(void);
void another(void);
int main(void)
{
    using debts::Debt;
    using debts::showDebt;
    Debt golf = {{"Benny", "Goatsniff"}, 120.0};
    showDebt(golf);
    other();
    another();

    return 0;
}

void other(void)
{
    using std::cout;
    using std::endl;
    using namespace debts;
    Person dg = {"Doodles", "Glister"};
    showPerson(dg);
    cout<<endl;
    Debt zippy[3];
    int i;

    for(i = 0; i<3; i++)
        getDebt(zippy[i]);
    for(i = 0; i<3; i++)
        showDebt(zippy[i]);
    cout<<"Total debt: $"<<sumDebts(zippy, 3)<<endl;
    return ;  // Dieser return ist auch ueberfluessig
}

void another(void)
{
    using pers::Person;;

    Person collector = {"Milo", "Rightshift"};
    pers::showPerson(collector);
    std::cout<<std::endl;
}
  

自由,民主,平等,博爱,进步.
中华民国,我的祖国,中华民国万岁!中华民国加油!
本人自愿加入中国国民党,为人的自由性,独立性和平等性而奋斗!
2005-01-08 18:36
kai
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:52
帖 子:3450
专家分:59
注 册:2004-4-25
收藏
得分:0 
//  number to string:

我们可以通过以下3种方法将一个数值转换为字符串.

---------

1. std::ostringstream
C/C++ Code:
#include <sstream>
#include <string>
#include <iostream>
#include <cstdlib>
using namespace std;
int main()
{
    double d = 1.23456;
    ostringstream Str;
    Str << d;
    string numToString(Str.str());
    cout << numToString << endl;
   
    system("pause");
    return EXIT_SUCCESS;
}

2. std::ostrstream
C/C++ Code:
#include <strstream>
#include <string>
#include <iostream>
#include <cstdlib>
using namespace std;

int main()
{
    double d = 1.23456;
    char buffer[10];
    ostrstream Str(buffer, 10);
    Str << d << ends;
    string numToString(Str.str());
    cout << numToString << endl;
   
    system("pause");
    return EXIT_SUCCESS;
}
3. sprintf
C/C++ Code:
#include <stdio.h>
#include <cstdlib>

int main()
{
    double d = 1.2345;
    char buffer[10];
    sprintf(buffer, "%g", d);
    printf("%s\n", buffer);
   
    std::system("pause");
    return EXIT_SUCCESS;
}

自由,民主,平等,博爱,进步.
中华民国,我的祖国,中华民国万岁!中华民国加油!
本人自愿加入中国国民党,为人的自由性,独立性和平等性而奋斗!
2005-01-29 21:58
kai
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:52
帖 子:3450
专家分:59
注 册:2004-4-25
收藏
得分:0 
猫妓, 看来你还没有理解题意,你再想想,为什么是3次而不是2次?

自由,民主,平等,博爱,进步.
中华民国,我的祖国,中华民国万岁!中华民国加油!
本人自愿加入中国国民党,为人的自由性,独立性和平等性而奋斗!
2005-02-11 08:11
kai
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:52
帖 子:3450
专家分:59
注 册:2004-4-25
收藏
得分:0 
你上面的话是对的,但是与"9999" 中 "99" 出现几次没有联系啊。

假设问你"99"  中 出现 "99" 几次,答案毫无疑问为  1  次。
 "999" 中 出现 "99" 几次呢? 答案应该为2次, 因为第一个字符和第二个字符为一次 "99",  第二个字符和第三个字符为一次 "99", 所以为2次.
那么"9999" 中出现 "99" 几次呢? 答案为3次.  如果你回答我 2 次, 那我问你哪两次呢? 你回答我 字符1,2 和字符3,4. 那我问你 字符2,3 难道不是 "99" 吗?  所以,你现在应该明白了吧...
 

自由,民主,平等,博爱,进步.
中华民国,我的祖国,中华民国万岁!中华民国加油!
本人自愿加入中国国民党,为人的自由性,独立性和平等性而奋斗!
2005-02-11 20:50
kai
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:52
帖 子:3450
专家分:59
注 册:2004-4-25
收藏
得分:0 
PLEASE SEE FROM 17 FLOOR, THEN YOU WILL KNOW WHAT "USING NAMESPACE STD" IS.

自由,民主,平等,博爱,进步.
中华民国,我的祖国,中华民国万岁!中华民国加油!
本人自愿加入中国国民党,为人的自由性,独立性和平等性而奋斗!
2005-05-20 19:35
快速回复:All about C++
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.024371 second(s), 10 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved