Объявление пространства имен в основном файле не переносится на заголовочные файлы: «используя пространство имен std;» - PullRequest
0 голосов
/ 16 марта 2019

Мой преподаватель предоставил моему классу один файл .cpp, содержащий мою основную функцию, а также три заголовочных файла для трех разных классов. В основном файле он использует "использование пространства имен std;" объявить пространство имен для проекта.

Мне известно, что "использование пространства имен std;" Это плохая практика, и ее следует избегать любой ценой, но учитель настаивает на трех важных моментах в завершении проекта:

  1. Вы не должны изменять любой из предоставленных файлов. «Ни одного персонажа». (Снижение оценки на 60%)
  2. Не удается собрать в Visual Studio 2017. (снижение оценки на 60%)
  3. Вылетает при нормальной работе. (Снижение на 60%)

Моя проблема заключается в том, что пространство имен, объявленное в главном файле (посредством использования «using namespace std;»), похоже, не переносится на файлы заголовков.

Вот основной файл:

// ass2.cpp
#define _CRT_SECURE_NO_WARNINGS
#define _CRTDBG_MAP_ALLOC   // need this to get the line identification
//_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF|_CRTDBG_LEAK_CHECK_DF); // in main, after local declarations
//NB must be in debug build
#include <crtdbg.h>
#include <iostream>
#include <string>
#include <vector>
#include <forward_list>
using namespace std; // THE NAMESPACE DECLARATION
#include "Frame.h"
#include "Animation.h"
#include "AnimationManager.h"

int main(void)
{
    char response;
    bool RUNNING = true;
    AnimationManager M("Manager1");
    _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);

    while (RUNNING)
    {
        cout << "MENU\n 1. Add an Animation\n 2. Delete an Animation\n 3. Edit an Animation\n 4. list the Animations\n 5. Quit" << endl;
        cin >> response;
        switch (response)
        {
        case '1':cin >> M; break;
        case '2':M.DeleteAnimation(); break;
        case '3':M.EditAnimation(); break;
        case '4':cout << M; break;
        case '5':RUNNING = false; break;
        default:cout << "Please enter a valid option" << endl;
        }
    }
    return 0;
}

Вот один из заголовочных файлов, остальные имеют одинаковую конструкцию:

//Animation.h
#pragma once

class Animation
{
    string animationName;
    forward_list<Frame> frames;
public:
    Animation(string name) :animationName(name) {}
    ~Animation() {}
    void EditFrame();
    void DeleteFrame();
    friend istream& operator>>(istream&, Animation&);// Add a Frame as in cin >> A;
    friend ostream& operator<<(ostream&, Animation&);// output the Frames as in cout << A;
};

Я создал тестовый файл, воссоздающий возникновение, оператор using namespace std; был помещен перед операторами #include "xxx.h".

Основной файл для созданного мной тестового пространства:

//: C12:IostreamOperatorOverloading.cpp
// Modified
// From Thinking in C++, 2nd Edition
// Available at http://www.BruceEckel.com
// (c) Bruce Eckel 2000
// Copyright notice in Copyright.txt
#define _CRT_SECURE_NO_WARNINGS
#define _CRTDBG_MAP_ALLOC   // need this to get the line identification
#include <iostream>
#include <crtdbg.h>
using namespace std;
#include "IntArray.h"

    int main() {
        char q;
        IntArray I, J;
        _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
        cout << "Overloaded extraction" << endl;
        cin >> I;
        cout << "Overloaded insertion" << endl;
        cout << I;
        cout << "Chained extraction" << endl;
        cin >> I >> J;
        cout << "Chained Insertion" << endl;
        cout << I << J;
        cout << "***********overloaded operator[] - returns an l-value*************" << endl << endl;
        I[4] = -1;
        J[0] = 99;
        cout << I << J;
        cout << "*******a returned r-value assigned to a returned l-value************" << endl << endl;
        I[0] = I[4];
        J[0] = I[1] = J[2];     // chained indexing
        cout << I << J;
        cout << endl << "********or, using explicit function calls (never do it this way) ********" << endl;
        operator>>(operator>>(cin, I), J);  //  cin >> I >> J;
        operator<<(operator<<(cout, I), J); //  cout << I <<  J;
        cout << "**************************************************" << endl;
        I.operator[](4) = -1;   // I[4] = -1;
        J.operator[](0) = 99;   // J[0] = 99;
        operator<<(operator<<(cout, I), J); // cout << I <<  J;
        cout << "**************************************************" << endl;
        I.operator[](0) = I.operator[](4);  // a returned r-value assigned to a returned l-value
        J.operator[](0) = I.operator[](1) = J.operator[](2);    // chained indexing
        operator<<(operator<<(cout, I), J);
        cout << "**************************************************" << endl;

        cin >> q;
    } ///:~

Заголовочный файл для созданного мной тестового пространства:

#pragma once

class IntArray {

    enum { sz = 5 };
    int i[sz];

public:

    IntArray() { memset(i, 0, sz * sizeof(*i)); }

    // Overloaded indexing operator
    int& operator[](int x) {
        return i[x];
    }

    // non-member friend overloaded operators - global functions
    // a friend has access to the private members of the class
    friend ostream&  operator<<(ostream& os, IntArray& ia); // overloaded insertion operator global function
    friend istream&  operator>>(istream& is, IntArray& ia); // overloaded extraction operator global function
};

.cpp файл для созданного мной тестового пространства, содержащий определения для функций класса IntArray:

#include <iostream>
#include "IntArray.h"
using namespace std;

std::ostream& operator<<(std::ostream& os, IntArray& ia) {
    for (int j = 0; j < ia.sz; j++) {
        //    os << ia.i[j];    // OK, this is the primitive way.
        os << ia[j];        // Better, now we have overloaded indexing.
        if (j != ia.sz - 1)
            os << ", ";
    }
    os << std::endl;
    return os;
}

std::istream& operator>>(std::istream& is, IntArray& ia) {
    for (int j = 0; j < ia.sz; j++)
        //   is >> ia.i[j]; // OK, this is the primitive way.
        is >> ia[j];        // Better, now we have overloaded indexing.
    return is;
}

И, наконец, вот пример ошибок, которые вылились мне в лицо из тестового файла, воссоздающего вхождение:

1>------ Build started: Project: PTR, Configuration: Debug Win32 ------
1>IntArray.cpp
1>c:\users\ali-g\desktop\cst8219\ptr\ptr\intarray.h(19): error C2143: syntax error: missing ';' before '&'
1>c:\users\ali-g\desktop\cst8219\ptr\ptr\intarray.h(19): error C2433: 'ostream': 'friend' not permitted on data declarations
1>c:\users\ali-g\desktop\cst8219\ptr\ptr\intarray.h(19): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\users\ali-g\desktop\cst8219\ptr\ptr\intarray.h(19): error C2238: unexpected token(s) preceding ';'
1>c:\users\ali-g\desktop\cst8219\ptr\ptr\intarray.h(20): error C2143: syntax error: missing ';' before '&'
1>c:\users\ali-g\desktop\cst8219\ptr\ptr\intarray.h(20): error C2433: 'istream': 'friend' not permitted on data declarations
1>c:\users\ali-g\desktop\cst8219\ptr\ptr\intarray.h(20): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\users\ali-g\desktop\cst8219\ptr\ptr\intarray.h(20): error C2238: unexpected token(s) preceding ';'
1>c:\users\ali-g\desktop\cst8219\ptr\ptr\intarray.cpp(6): error C2248: 'IntArray::sz': cannot access private enumerator declared in class 'IntArray'
1>c:\users\ali-g\desktop\cst8219\ptr\ptr\intarray.h(5): note: see declaration of 'IntArray::sz'
1>c:\users\ali-g\desktop\cst8219\ptr\ptr\intarray.h(3): note: see declaration of 'IntArray'
1>c:\users\ali-g\desktop\cst8219\ptr\ptr\intarray.cpp(9): error C2248: 'IntArray::sz': cannot access private enumerator declared in class 'IntArray'
1>c:\users\ali-g\desktop\cst8219\ptr\ptr\intarray.h(5): note: see declaration of 'IntArray::sz'
1>c:\users\ali-g\desktop\cst8219\ptr\ptr\intarray.h(3): note: see declaration of 'IntArray'
1>c:\users\ali-g\desktop\cst8219\ptr\ptr\intarray.cpp(17): error C2248: 'IntArray::sz': cannot access private enumerator declared in class 'IntArray'
1>c:\users\ali-g\desktop\cst8219\ptr\ptr\intarray.h(5): note: see declaration of 'IntArray::sz'
1>c:\users\ali-g\desktop\cst8219\ptr\ptr\intarray.h(3): note: see declaration of 'IntArray'
1>Done building project "PTR.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

Я обнаружил, что добавив "using namespace std;" Утверждение в верхней части заголовочных файлов (что является ОЧЕНЬ ПЛОХОЙ практикой) решает проблему, но это обойдется мне в 60% от отметок о назначении, поскольку оно нарушает первый из трех его важных пунктов.

Я был бы очень признателен за помощь в решении этой проблемы. Я читал об этой проблеме в течение последних нескольких часов, но это (для меня) очень необычный случай ... Спасибо всем!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...