Giter VIP home page Giter VIP logo

Comments (10)

pezy avatar pezy commented on September 28, 2024

我按照你给的代码在vs2015上,在clear函数体内的s.contents,s.height , s.width,编译器会显示警告不可访问。

你是不是少写了 friend void Window_mgr::clear(ScreenIndex);

不知道是什么问题。难道是编译器的问题?

我测试了一下,在 VS 2015 上,ex7.32 并没有什么问题。

from cppprimer.

l3518563 avatar l3518563 commented on September 28, 2024

我是直接复制粘贴代码的,提示是这样的
严重性 代码 说明 项目 文件 行
错误(活动) 成员 "Screen::contents" (已声明 所在行数:54) 不可访问 ConsoleApplication11 c:\Users\Administrator.0KMF4QN6XAERFK5\Documents\Visual Studio 2015\Projects\ConsoleApplication11\ConsoleApplication11\标头.h 61

from cppprimer.

pezy avatar pezy commented on September 28, 2024

我是直接复制粘贴代码的,提示是这样的

那请你贴出完整的代码,答案里只有头文件,您的 main 函数是怎样的呢?

from cppprimer.

why2cs avatar why2cs commented on September 28, 2024

@pezy 前辈你好。正好也做到了这一题,你的代码在vs2015也编译通过。

但是有一个问题能否麻烦简单解答一下?如果 Window_mgr 类和 Screen 类在两个头文件中,相应的代码应如何设计?我自己搞了半天没搞出来,能否简单提示下,谢谢!

from cppprimer.

pezy avatar pezy commented on September 28, 2024

@why2cs Window_mgr 类的头文件中,仅需要用到 Screen 类的前置声明即可。

window_mgr.h

#pragma once
#include <vector>

class Screen;
class Window_mgr {
public:
    using ScreenIndex = std::vector<Screen>::size_type;
    inline void clear(ScreenIndex);
private:
    std::vector<Screen> screens;
};

window_mgr.cpp

#include "window_mgr.h"
#include "screen.h"

inline void Window_mgr::clear(ScreenIndex i)
{
    if (i >= screens.size()) return; // judge for out_of_range.
    Screen& s = screens[i];
    s.contents = std::string(s.height * s.width, ' ');
}

screen.h

#pragma once

#include <vector>
#include <string>
#include <iostream>

#include "window_mgr.h"

class Screen {
    friend void Window_mgr::clear(ScreenIndex);

public:
    using pos = std::string::size_type;

    Screen() = default; // 1
    Screen(pos ht, pos wd) : height(ht), width(wd), contents(ht * wd, ' ') {} // 2
    Screen(pos ht, pos wd, char c) : height(ht), width(wd), contents(ht * wd, c){} // 3

    char get() const { return contents[cursor]; }
    char get(pos r, pos c) const { return contents[r * width + c]; }
    inline Screen& move(pos r, pos c);
    inline Screen& set(char c);
    inline Screen& set(pos r, pos c, char ch);

    const Screen& display(std::ostream& os) const
    {
        do_display(os);
        return *this;
    }
    Screen& display(std::ostream& os)
    {
        do_display(os);
        return *this;
    }

private:
    void do_display(std::ostream& os) const { os << contents; }

private:
    pos cursor = 0;
    pos height = 0, width = 0;
    std::string contents;
};

inline Screen& Screen::move(pos r, pos c)
{
    cursor = r * width + c;
    return *this;
}

inline Screen& Screen::set(char c)
{
    contents[cursor] = c;
    return *this;
}

inline Screen& Screen::set(pos r, pos c, char ch)
{
    contents[r * width + c] = ch;
    return *this;
}

from cppprimer.

why2cs avatar why2cs commented on September 28, 2024

谢谢啦!我发现我的问题出在哪了。

在之前的练习中,我将Window_mgr.h头文件中包含了Screen.h,接着在Window_mgr做了一个类内初始值。如下:
std::vector<Screen> screens{Screen(5,5,'X')};
然后在做这个练习的时候,因为要在Screen类中友元声明Window_mgr::clear,导致:

1.Window_mgr头文件包含有#include "Screen.h",并含有Screen类的前置声明(此时前置声明已无意义)。
2.Screen头文件中包含有#include "Window_mgr.h"

编译时出现问题。麻烦问一下:
1.如果一定要实现screens的类内初始值的话,该怎样做呢?还是根本就不能这样?
2.你的clear函数定义在cpp文件中,如果要定义在Window_mgr.h中,该怎么做呢?

第一次用github,也不太会提问和编辑,谢谢啦。

from cppprimer.

pezy avatar pezy commented on September 28, 2024

@why2cs

前置声明,是告诉编译器,我这里仅仅只会用到某类的声明,而非定义。
include 头文件是将整个类的定义包含了进来。

如果一定要实现screens的类内初始值的话,该怎样做呢?还是根本就不能这样?

初始化,与声明不同,是必须包含整个类定义的。所以一定要实现的话,你就得 #include "screen.h";然而在 Screen 类中,又用到了 Window_mgr 的友元函数,这个也是一定要包含整个类定义的,也必须要 #include "window_mgr.h" 这样互相包含,就成了死局,编译器自然就要报错了。所以结论是,没办法这么做。

你的clear函数定义在cpp文件中,如果要定义在Window_mgr.h中,该怎么做呢?

和上面讲的一样,clear 函数中,需要用到 Screen 类的定义,所以引入 "screen.h" 是必须的,如果你非要定义在 Window_mgr 中,则又会出现上面描述过的那种死局。我将定义分离到 cpp 里,就是为了避免这样的死局。所以结论依然是,没有办法这么做。

from cppprimer.

why2cs avatar why2cs commented on September 28, 2024

好的,非常感谢 @pezy 的耐心回答,这个问题解决掉啦!

from cppprimer.

l3518563 avatar l3518563 commented on September 28, 2024

我没有写相应的程序代码,刚试着写了一下不太会写,大神能不能贴一下你的代码让我参考学习一下。

from cppprimer.

pezy avatar pezy commented on September 28, 2024

我没有写相应的程序代码,刚试着写了一下不太会写

不明白您不会写什么,个人建议您再好好看看书吧。

from cppprimer.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.